use hyper::StatusCode; use sibyl::Row; use crate::{ServiceInner, error::ServiceError, model::{PersonBody, Person, Address, PersonQuery}}; impl ServiceInner { pub async fn get_persons(&self, filter: PersonQuery) -> Result, ServiceError> { let session = self.pool.get_session().await?; let stmt = session.prepare(" SELECT p.personId, p.name, p.lastName, p.age, ad.street, ad.houseNumber, ad.postalCode, ad.city, ad.country FROM Person p INNER JOIN Address ad ON p.addressId = ad.addressId WHERE p.name LIKE :FIRST AND p.lastName LIKE :LAST ").await?; let rows = stmt.query(( (":FIRST", format!("%{}%", filter.firstname.unwrap_or_default())), (":LAST", format!("%{}%", filter.lastname.unwrap_or_default())) )).await?; let mut persons: Vec = vec![]; while let Some(row) = rows.next().await? { persons.push(Self::map_person_row(row, 0)?); } Ok(persons) } pub async fn get_person(&self, id: i32) -> Result, ServiceError> { let session = self.pool.get_session().await?; let stmt = session.prepare(" SELECT p.personId, p.name, p.lastName, p.age, ad.street, ad.houseNumber, ad.postalCode, ad.city, ad.country FROM Person p INNER JOIN Address ad ON p.addressId = ad.addressId WHERE p.personId = :ID ").await?; let row = stmt.query_single(id).await?; Ok(match row { Some(row) => { Some(Self::map_person_row(row, 0)?) }, None => None, }) } pub async fn add_person(&self, person: PersonBody) -> Result { let session = self.pool.get_session().await?; let stmt = session.prepare(" BEGIN addPerson(:FIRST, :LAST, :AGE, :STREET, :HOUSE, :POSTAL, :CITY, :COUNTRY); END; ").await?; stmt.execute(( (":FIRST", person.first_name), (":LAST", person.last_name), (":AGE", person.age), (":STREET", person.address.street), (":HOUSE", person.address.house_number), (":POSTAL", person.address.postal_code), (":CITY", person.address.city), (":COUNTRY", person.address.country) )).await?; let stmt = session.prepare("SELECT PERSON_SEQ.currval FROM dual").await?; let row = stmt.query_single("").await? .ok_or_else(|| ServiceError::ErrorResponse(StatusCode::INTERNAL_SERVER_ERROR, None))?; let id: i32 = row.get(0)?; Ok(id) } pub fn map_person_row(row: Row, offset: usize) -> Result { Ok(Person { id: row.get(0 + offset)?, first_name: row.get(1 + offset)?, last_name: row.get(2 + offset)?, age: row.get(3 + offset)?, address: Address { street: row.get(4 + offset)?, house_number: row.get(5 + offset)?, postal_code: row.get(6 + offset)?, city: row.get(7 + offset)?, country: row.get(8 + offset)?, } }) } }