use diesel::pg::Pg;
use diesel::query_dsl::methods::FilterDsl;
use diesel::{debug_query, ExpressionMethods, QueryDsl, QueryResult};
use diesel_async::{AsyncConnection, AsyncPgConnection, RunQueryDsl};
use futures_util::Future;
use log::debug;
use uuid::Uuid;
use crate::model::entity::drawings::{Drawing, UpdateDrawing};
use crate::schema::{drawings, layers};
impl Drawing {
pub async fn find(map_id: i32, conn: &mut AsyncPgConnection) -> QueryResult<Vec<Self>> {
let query = FilterDsl::filter(
drawings::table.left_join(layers::table),
layers::map_id.eq(map_id),
)
.select(drawings::all_columns)
.into_boxed();
debug!("{}", debug_query::<Pg, _>(&query));
query.load::<Self>(conn).await
}
pub async fn find_in_layer(
layer_id: Uuid,
conn: &mut AsyncPgConnection,
) -> QueryResult<Vec<Self>> {
let query = FilterDsl::filter(drawings::table, drawings::layer_id.eq(layer_id));
debug!("{}", debug_query::<Pg, _>(&query));
query.load::<Self>(conn).await
}
pub async fn create(
drawings: Vec<Self>,
conn: &mut AsyncPgConnection,
) -> QueryResult<Vec<Self>> {
let query = diesel::insert_into(drawings::table).values(&drawings);
debug!("{}", debug_query::<Pg, _>(&query));
query.get_results::<Self>(conn).await
}
pub async fn update(
drawing_updates: Vec<UpdateDrawing>,
conn: &mut AsyncPgConnection,
) -> QueryResult<Vec<Self>> {
conn.transaction(|transaction| {
Box::pin(async {
let ids: Vec<Uuid> = drawing_updates.iter().map(|u| u.id).collect();
let futures = Self::do_update(drawing_updates, transaction);
futures_util::future::try_join_all(futures).await?;
let results = FilterDsl::filter(
drawings::table.select(drawings::all_columns),
drawings::id.eq_any(ids),
)
.load::<Self>(transaction)
.await?;
Ok(results) as QueryResult<Vec<Self>>
})
})
.await
}
fn do_update(
updates: Vec<UpdateDrawing>,
conn: &mut AsyncPgConnection,
) -> Vec<impl Future<Output = QueryResult<Self>>> {
let mut futures = Vec::with_capacity(updates.len());
for update in updates {
let updated_drawings = diesel::update(drawings::table.find(update.id))
.set(update)
.get_result::<Self>(conn);
futures.push(updated_drawings);
}
futures
}
pub async fn delete_by_ids(ids: Vec<Uuid>, conn: &mut AsyncPgConnection) -> QueryResult<usize> {
let query = diesel::delete(FilterDsl::filter(drawings::table, drawings::id.eq_any(ids)));
debug!("{}", debug_query::<Pg, _>(&query));
query.execute(conn).await
}
}