use diesel::{
dsl::delete,
prelude::*,
sql_types::{Binary, Integer, Nullable, Text},
};
use crate::admin::store::{
diesel::models::CircuitMemberModel,
diesel::schema::{circuit, circuit_member, node_endpoint},
error::AdminServiceStoreError,
};
use super::{get_circuit::AdminServiceStoreFetchCircuitOperation, AdminServiceStoreOperations};
pub(in crate::admin::store::diesel) trait AdminServiceStoreRemoveCircuitOperation {
fn remove_circuit(&self, circuit_id: &str) -> Result<(), AdminServiceStoreError>;
}
impl<'a, C> AdminServiceStoreRemoveCircuitOperation for AdminServiceStoreOperations<'a, C>
where
C: diesel::Connection,
String: diesel::deserialize::FromSql<diesel::sql_types::Text, C::Backend>,
i64: diesel::deserialize::FromSql<diesel::sql_types::BigInt, C::Backend>,
i32: diesel::deserialize::FromSql<diesel::sql_types::Integer, C::Backend>,
i16: diesel::deserialize::FromSql<diesel::sql_types::SmallInt, C::Backend>,
CircuitMemberModel: diesel::Queryable<(Text, Text, Integer, Nullable<Binary>), C::Backend>,
{
fn remove_circuit(&self, circuit_id: &str) -> Result<(), AdminServiceStoreError> {
self.conn.transaction::<(), _, _>(|| {
self.get_circuit(circuit_id).and_then(|opt_circuit| {
delete(circuit::table.find(&circuit_id)).execute(self.conn)?;
if let Some(circuit) = opt_circuit {
for node in circuit.members() {
if let Some(0) = circuit_member::table
.filter(circuit_member::node_id.eq(&node.node_id()))
.count()
.first(self.conn)
.optional()?
{
delete(
node_endpoint::table
.filter(node_endpoint::node_id.eq(node.node_id())),
)
.execute(self.conn)?;
}
}
}
Ok(())
})
})
}
}