use serde::Deserialize; use anyhow::Error; use anyhow::Result; use diesel::ExpressionMethods; use diesel::RunQueryDsl; use diesel::query_dsl::methods::FilterDsl; use diesel::Connection; use crate::db::DbPool; use crate::schema::countries; #[derive(Debug, Deserialize, diesel::Queryable, getset::Getters)] pub struct Country { id: i32, #[getset(get = "pub")] name: String, } #[derive(Insertable)] #[table_name = "countries"] struct NewCountry<'a> { name: &'a str } impl Country { pub fn create_or_fetch(db: &DbPool, name: &str) -> Result { use crate::schema; let conn = db.get()?; conn.transaction::<_, Error, _>(|| { let new_country = NewCountry { name }; diesel::insert_into(schema::countries::table) .values(&new_country) .on_conflict_do_nothing() .execute(&conn)?; schema::countries::table .filter(schema::countries::name.eq(name)) .first::(&conn) .map_err(Error::from) }) } }