use anyhow::Error; use anyhow::Result; use diesel::ExpressionMethods; use diesel::RunQueryDsl; use diesel::query_dsl::methods::FilterDsl; use diesel::Connection; use diesel::BoolExpressionMethods; use crate::db::DbPool; use crate::model::Address; use crate::schema::persons; use crate::schema; #[derive(Debug, diesel::Associations, diesel::Queryable, getset::Getters, getset::CopyGetters)] #[belongs_to(Address)] #[table_name = "persons"] pub struct Person { #[getset(get_copy = "pub")] id: i32, #[getset(get = "pub")] name: String, #[getset(get_copy = "pub")] age: i32, address_id: i32, } #[derive(Insertable)] #[table_name = "persons"] struct NewPerson<'a> { name: &'a str, age: i32, address_id: i32, } impl Person { pub fn create_or_fetch(db: &DbPool, addr: &Address, name: &str, age: i32) -> Result { let conn = db.get()?; conn.transaction::<_, Error, _>(|| { let new_person = NewPerson { name, age, address_id: addr.id, }; diesel::insert_into(schema::persons::table) .values(&new_person) .on_conflict_do_nothing() .execute(&conn)?; schema::persons::table .filter({ schema::persons::name.eq(name) .and(schema::persons::age.eq(age)) .and(schema::persons::address_id.eq(addr.id)) }) .first::(&conn) .map_err(Error::from) }) } pub fn address(&self, db: &DbPool) -> Result
{ schema::address::table .filter(schema::address::id.eq(self.address_id)) .first::
(&db.get()?) .map_err(Error::from) } pub fn fetch_by_id(db: &DbPool, id: i32) -> Result> { use diesel::QueryDsl; use diesel::OptionalExtension; schema::persons::dsl::persons.find(id) .first::(&db.get()?) .optional() .map_err(Error::from) } }