From de6519c70100a1512fbefb9a6f320e3d77a98e28 Mon Sep 17 00:00:00 2001 From: Vinod J M Date: Wed, 26 Oct 2022 16:49:55 +0530 Subject: [PATCH] v0.09 --- backend/Cargo.lock | 1 + backend/api/Cargo.toml | 1 + backend/api/src/lib.rs | 188 ++++++++++++++++-- backend/entity/src/entities/book.rs | 22 +- .../src/m20220101_000001_create_table.rs | 22 +- backend/orm/src/mutation.rs | 9 +- 6 files changed, 195 insertions(+), 48 deletions(-) diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 2e56701..0959f77 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -423,6 +423,7 @@ dependencies = [ "clap", "entity", "error-chain", + "itertools", "log", "reqwest", "sea-orm", diff --git a/backend/api/Cargo.toml b/backend/api/Cargo.toml index bf9c08d..80f7c6e 100644 --- a/backend/api/Cargo.toml +++ b/backend/api/Cargo.toml @@ -20,6 +20,7 @@ tower = "^0.4" tower-http = { version = "^0.3", features = ["full"] } tracing = "^0.1" tracing-subscriber = "^0.3" +itertools = "0.10" [dependencies.sea-orm] version = "^0.9.2" # sea-orm version diff --git a/backend/api/src/lib.rs b/backend/api/src/lib.rs index 5f1f5e5..646ce1d 100644 --- a/backend/api/src/lib.rs +++ b/backend/api/src/lib.rs @@ -15,19 +15,47 @@ use tower::ServiceBuilder; use tower_http::cors::CorsLayer; use tower_http::trace::TraceLayer; use booksman_orm::{ - sea_orm::{Database, DatabaseConnection}, + sea_orm::{Database, DatabaseConnection, ActiveValue}, Mutation as MutationCore, Query as QueryCore, }; +use itertools::Itertools; +use std::iter::Peekable; use ::entity::entities::{book,book_author,book_person,book_place,book_subject,book_time,book_isbn}; -#[derive(Deserialize, Serialize, Debug)] +#[derive(Deserialize, Serialize, Debug, Clone)] +struct BookUI { + id: i32, + open_library_key: Option, + title: String, + edition_count: Option, + first_publish_year: Option, + median_page_count: Option, + goodread_id: Option, + description: Option, + cover: Option, + location: Option, + time_added: Option, + rating: Option, + comments: Option, + author_name: Option>, + person: Option>, + place: Option>, + subject: Option>, + time: Option>, + isbn: Option>, +} + +#[derive(Deserialize, Serialize, Debug, Clone)] struct Docs { key: String, title: String, - first_publish_year: Option, - number_of_pages_median: Option, + edition_count: Option, + first_publish_year: Option, + number_of_pages_median: Option, + goodread_id: Option, + description: Option, isbn: Option>, - cover_i: Option, + cover_i: Option, cover_url: Option, author_name: Option>, person: Option>, @@ -133,9 +161,35 @@ async fn search_openlibrary( resjson.docs.truncate(10); resjson.set_all_cover_urls(); print!("Search token {:?}\n", search); - return Json(resjson); +let mut vec = Vec::with_capacity(10); + for i in 0..10 as usize { + let doc = resjson.docs[i].clone(); + vec.push( +BookUI{ + id: (i+1) as i32, +open_library_key: Some(doc.key), +title: doc.title, +edition_count: doc.edition_count, +first_publish_year: doc.first_publish_year, +median_page_count: doc.number_of_pages_median, +goodread_id: doc.goodread_id, +description: doc.description, +cover: doc.cover_url, +location: None, +time_added: None, +rating: None, +comments: None, +author_name: doc.author_name, +person: doc.person, +place: doc.place, +subject: doc.subject, +time: doc.time, +isbn: doc.isbn +} + ); +} + return Json(vec); } - async fn delete_book( Extension(ref conn): Extension, @@ -150,34 +204,126 @@ async fn delete_book( async fn list_book( Extension(ref conn): Extension, ) -> impl IntoResponse { - let books = QueryCore::find_books_in_page(conn,1,5) + let books = QueryCore::find_books_plus_meta_in_page(conn,1,5) .await .expect("could not list books"); - "success" +let res: Vec = (books.0).iter() + .group_by(|x| (x.id, x.title.clone()) ).into_iter().peekable() + .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()), + }).collect(); +return Json(res); + // "success" } async fn create_book( Extension(ref conn): Extension, - doc_sent : Form, + doc_sent : Form, ) -> impl IntoResponse { let book: book::Model = book::Model{ - open_library_key: "NONE".to_string(), + open_library_key: doc_sent.open_library_key.to_owned(), title: (doc_sent.title.to_owned()), - edition_count: 1, - first_publish_year: 1,//(doc_sent.first_publish_year.unwrap().to_owned()), - median_page_count: 1, //(doc_sent.number_of_pages_median.unwrap().to_owned()), - goodread_id: "NONE".to_string(), - description: "NONE".to_string(), - comments: "NONE".to_string(), - cover: "NONE".to_string(), - rating: 1, - time_added: "NONE".to_string(), + edition_count: doc_sent.edition_count.to_owned(), + first_publish_year: (doc_sent.first_publish_year.to_owned()), + median_page_count: (doc_sent.median_page_count.to_owned()), + goodread_id: doc_sent.goodread_id.to_owned(), + description: doc_sent.description.to_owned(), + comments: doc_sent.comments.to_owned(), + cover: doc_sent.cover.to_owned(), + rating: doc_sent.rating.to_owned(), + time_added: doc_sent.time_added.to_owned(), id: 1, - location: "NONE".to_string(), + location: doc_sent.location.to_owned(), }; let created_book = MutationCore::create_book(conn, book) .await .expect("could not create book"); + + for author_name in doc_sent.author_name.as_ref().unwrap().iter() { + let record : book_author::Model = book_author::Model{ + id: 1, + book_id: (created_book.last_insert_id), + author_name: author_name.to_owned(), + }; + MutationCore::create_book_author(conn, record) + .await + .expect("could not create book"); + } + for person in doc_sent.person.as_ref().unwrap().iter() { + let record : book_person::Model = book_person::Model{ + id: 1, + book_id: (created_book.last_insert_id), + person: person.to_owned(), + }; + MutationCore::create_book_person(conn, record) + .await + .expect("could not create book"); + + } + for place in doc_sent.place.as_ref().unwrap().iter() { + let record : book_place::Model = book_place::Model{ + id: 1, + book_id: (created_book.last_insert_id), + place: place.to_owned(), + }; + MutationCore::create_book_place(conn, record) + .await + .expect("could not create book"); + + } + for subject in doc_sent.subject.as_ref().unwrap().iter() { + let record : book_subject::Model = book_subject::Model{ + id: 1, + book_id: (created_book.last_insert_id), + subject: subject.to_owned(), + }; + MutationCore::create_book_subject(conn, record) + .await + .expect("could not create book"); + + } + for time in doc_sent.time.as_ref().unwrap().iter() { + let record : book_time::Model = book_time::Model{ + id: 1, + book_id: (created_book.last_insert_id), + time: time.to_owned(), + }; + MutationCore::create_book_time(conn, record) + .await + .expect("could not create book"); + + } + for isbn in doc_sent.isbn.as_ref().unwrap().iter() { + let record : book_isbn::Model = book_isbn::Model{ + id: 1, + book_id: (created_book.last_insert_id), + isbn: isbn.to_owned(), + }; + MutationCore::create_book_isbn(conn, record) + .await + .expect("could not create book"); + + } + + "success" } diff --git a/backend/entity/src/entities/book.rs b/backend/entity/src/entities/book.rs index 0f94df2..8ae4d54 100644 --- a/backend/entity/src/entities/book.rs +++ b/backend/entity/src/entities/book.rs @@ -7,18 +7,18 @@ use sea_orm::entity::prelude::*; pub struct Model { #[sea_orm(primary_key)] pub id: i32, - pub open_library_key: String, + pub open_library_key: Option, pub title: String, - pub edition_count: i32, - pub first_publish_year: i32, - pub median_page_count: i32, - pub goodread_id: String, - pub description: String, - pub cover: String, - pub location: String, - pub time_added: String, - pub rating: i32, - pub comments: String, + pub edition_count: Option, + pub first_publish_year: Option, + pub median_page_count: Option, + pub goodread_id: Option, + pub description: Option, + pub cover: Option, + pub location: Option, + pub time_added: Option, + pub rating: Option, + pub comments: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/backend/migration/src/m20220101_000001_create_table.rs b/backend/migration/src/m20220101_000001_create_table.rs index f0e83f6..e775702 100644 --- a/backend/migration/src/m20220101_000001_create_table.rs +++ b/backend/migration/src/m20220101_000001_create_table.rs @@ -22,18 +22,18 @@ impl MigrationTrait for Migration { .auto_increment() .primary_key(), ) - .col(ColumnDef::new(Book::OpenLibraryKey).string().not_null()) + .col(ColumnDef::new(Book::OpenLibraryKey).string()) .col(ColumnDef::new(Book::Title).string().not_null()) - .col(ColumnDef::new(Book::EditionCount).integer().not_null()) - .col(ColumnDef::new(Book::FirstPublishYear).integer().not_null()) - .col(ColumnDef::new(Book::MedianPageCount).integer().not_null()) - .col(ColumnDef::new(Book::GoodreadId).string().not_null()) - .col(ColumnDef::new(Book::Description).string().not_null()) - .col(ColumnDef::new(Book::Cover).string().not_null()) - .col(ColumnDef::new(Book::Location).string().not_null()) - .col(ColumnDef::new(Book::TimeAdded).time().not_null()) - .col(ColumnDef::new(Book::Rating).integer().not_null()) - .col(ColumnDef::new(Book::Comments).string().not_null()) + .col(ColumnDef::new(Book::EditionCount).integer()) + .col(ColumnDef::new(Book::FirstPublishYear).integer()) + .col(ColumnDef::new(Book::MedianPageCount).integer()) + .col(ColumnDef::new(Book::GoodreadId).string()) + .col(ColumnDef::new(Book::Description).string()) + .col(ColumnDef::new(Book::Cover).string()) + .col(ColumnDef::new(Book::Location).string()) + .col(ColumnDef::new(Book::TimeAdded).time()) + .col(ColumnDef::new(Book::Rating).integer()) + .col(ColumnDef::new(Book::Comments).string()) .to_owned(), ) .await; diff --git a/backend/orm/src/mutation.rs b/backend/orm/src/mutation.rs index 7c1653e..6d6acc3 100644 --- a/backend/orm/src/mutation.rs +++ b/backend/orm/src/mutation.rs @@ -12,8 +12,8 @@ impl Mutation { pub async fn create_book( db: &DbConn, form_data: book::Model, - ) -> Result { - book::ActiveModel { + ) -> Result, DbErr> { + let record = book::ActiveModel { open_library_key: Set(form_data.open_library_key.to_owned()), title: Set(form_data.title.to_owned()), edition_count: Set(form_data.edition_count.to_owned()), @@ -27,9 +27,8 @@ impl Mutation { rating: Set(form_data.rating.to_owned()), comments: Set(form_data.comments.to_owned()), ..Default::default() - } - .save(db) - .await + }; + Book::insert(record).exec(db).await } pub async fn create_book_author(