108 lines
3.5 KiB
Rust
108 lines
3.5 KiB
Rust
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<Vec<Person>, 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<Person> = 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<Option<Person>, 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<i32, ServiceError> {
|
|
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<Person, ServiceError> {
|
|
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)?,
|
|
}
|
|
})
|
|
}
|
|
|
|
} |