use diesel::prelude::*;
use crate::admin::store::{error::AdminServiceStoreError, CircuitBuilder, CircuitNode, Service};
use crate::error::InvalidStateError;
use super::{
add_circuit::AdminServiceStoreAddCircuitOperation,
get_proposal::AdminServiceStoreFetchProposalOperation,
remove_proposal::AdminServiceStoreRemoveProposalOperation, AdminServiceStoreOperations,
};
pub(in crate::admin::store::diesel) trait AdminServiceStoreUpgradeProposalToCircuitOperation {
fn upgrade_proposal_to_circuit(&self, circuit_id: &str) -> Result<(), AdminServiceStoreError>;
}
#[cfg(feature = "postgres")]
impl<'a> AdminServiceStoreUpgradeProposalToCircuitOperation
for AdminServiceStoreOperations<'a, diesel::pg::PgConnection>
{
fn upgrade_proposal_to_circuit(&self, circuit_id: &str) -> Result<(), AdminServiceStoreError> {
self.conn.transaction::<(), _, _>(|| {
let proposal = match self.get_proposal(circuit_id)? {
Some(proposal) => Ok(proposal),
None => Err(AdminServiceStoreError::InvalidStateError(
InvalidStateError::with_message(String::from(
"CircuitProposal does not exist in AdminServiceStore",
)),
)),
}?;
let proposed_circuit = proposal.circuit();
let mut builder = CircuitBuilder::new()
.with_circuit_id(proposed_circuit.circuit_id())
.with_roster(
&proposed_circuit
.roster()
.iter()
.map(Service::from)
.collect::<Vec<Service>>(),
)
.with_members(
&proposed_circuit
.members()
.iter()
.map(CircuitNode::from)
.collect::<Vec<CircuitNode>>(),
)
.with_authorization_type(proposed_circuit.authorization_type())
.with_persistence(proposed_circuit.persistence())
.with_durability(proposed_circuit.durability())
.with_routes(proposed_circuit.routes())
.with_circuit_management_type(proposed_circuit.circuit_management_type())
.with_circuit_version(proposed_circuit.circuit_version())
.with_circuit_status(proposed_circuit.circuit_status());
if let Some(display_name) = proposed_circuit.display_name() {
builder = builder.with_display_name(display_name);
}
let circuit = builder
.build()
.map_err(AdminServiceStoreError::InvalidStateError)?;
let circuit_nodes = proposed_circuit
.members()
.iter()
.map(CircuitNode::from)
.collect::<Vec<CircuitNode>>();
self.remove_proposal(proposal.circuit_id())
.and_then(|_| self.add_circuit(circuit, circuit_nodes))?;
Ok(())
})
}
}
#[cfg(feature = "sqlite")]
impl<'a> AdminServiceStoreUpgradeProposalToCircuitOperation
for AdminServiceStoreOperations<'a, diesel::sqlite::SqliteConnection>
{
fn upgrade_proposal_to_circuit(&self, circuit_id: &str) -> Result<(), AdminServiceStoreError> {
self.conn.transaction::<(), _, _>(|| {
let proposal = match self.get_proposal(circuit_id)? {
Some(proposal) => Ok(proposal),
None => Err(AdminServiceStoreError::InvalidStateError(
InvalidStateError::with_message(String::from(
"CircuitProposal does not exist in AdminServiceStore",
)),
)),
}?;
let proposed_circuit = proposal.circuit();
let mut builder = CircuitBuilder::new()
.with_circuit_id(proposed_circuit.circuit_id())
.with_roster(
&proposed_circuit
.roster()
.iter()
.map(Service::from)
.collect::<Vec<Service>>(),
)
.with_members(
&proposed_circuit
.members()
.iter()
.map(CircuitNode::from)
.collect::<Vec<CircuitNode>>(),
)
.with_authorization_type(proposed_circuit.authorization_type())
.with_persistence(proposed_circuit.persistence())
.with_durability(proposed_circuit.durability())
.with_routes(proposed_circuit.routes())
.with_circuit_management_type(proposed_circuit.circuit_management_type())
.with_circuit_version(proposed_circuit.circuit_version())
.with_circuit_status(proposed_circuit.circuit_status());
if let Some(display_name) = proposed_circuit.display_name() {
builder = builder.with_display_name(display_name);
}
let circuit = builder
.build()
.map_err(AdminServiceStoreError::InvalidStateError)?;
let circuit_nodes = proposed_circuit
.members()
.iter()
.map(CircuitNode::from)
.collect::<Vec<CircuitNode>>();
self.remove_proposal(proposal.circuit_id())
.and_then(|_| self.add_circuit(circuit, circuit_nodes))?;
Ok(())
})
}
}