use std::convert::TryFrom;
use diesel::{
dsl::{delete, insert_into, update},
prelude::*,
};
use super::AdminServiceStoreOperations;
use crate::admin::store::{
diesel::{
models::{
CircuitProposalModel, ProposedCircuitModel, ProposedNodeEndpointModel,
ProposedNodeModel, ProposedServiceArgumentModel, ProposedServiceModel, VoteRecordModel,
},
schema::{
circuit_proposal, proposed_circuit, proposed_node, proposed_node_endpoint,
proposed_service, proposed_service_argument, vote_record,
},
},
error::AdminServiceStoreError,
CircuitProposal,
};
use crate::error::InvalidStateError;
pub(in crate::admin::store::diesel) trait AdminServiceStoreUpdateProposalOperation {
fn update_proposal(&self, proposal: CircuitProposal) -> Result<(), AdminServiceStoreError>;
}
#[cfg(feature = "postgres")]
impl<'a> AdminServiceStoreUpdateProposalOperation
for AdminServiceStoreOperations<'a, diesel::pg::PgConnection>
{
fn update_proposal(&self, proposal: CircuitProposal) -> Result<(), AdminServiceStoreError> {
self.conn.transaction::<(), _, _>(|| {
circuit_proposal::table
.filter(circuit_proposal::circuit_id.eq(proposal.circuit_id()))
.first::<CircuitProposalModel>(self.conn)
.optional()?
.ok_or_else(|| {
AdminServiceStoreError::InvalidStateError(InvalidStateError::with_message(
String::from("CircuitProposal does not exist in AdminServiceStore"),
))
})?;
let proposal_model = CircuitProposalModel::from(&proposal);
update(circuit_proposal::table.find(proposal.circuit_id()))
.set((
circuit_proposal::proposal_type.eq(proposal_model.proposal_type),
circuit_proposal::circuit_hash.eq(proposal_model.circuit_hash),
circuit_proposal::requester.eq(proposal_model.requester),
circuit_proposal::requester_node_id.eq(proposal_model.requester_node_id),
))
.execute(self.conn)?;
let proposed_circuit_model = ProposedCircuitModel::from(proposal.circuit());
update(proposed_circuit::table.find(proposal.circuit_id()))
.set((
proposed_circuit::authorization_type
.eq(proposed_circuit_model.authorization_type),
proposed_circuit::persistence.eq(proposed_circuit_model.persistence),
proposed_circuit::durability.eq(proposed_circuit_model.durability),
proposed_circuit::routes.eq(proposed_circuit_model.routes),
proposed_circuit::circuit_management_type
.eq(proposed_circuit_model.circuit_management_type),
proposed_circuit::application_metadata
.eq(proposed_circuit_model.application_metadata),
proposed_circuit::comments.eq(proposed_circuit_model.comments),
))
.execute(self.conn)?;
delete(
proposed_node::table.filter(proposed_node::circuit_id.eq(proposal.circuit_id())),
)
.execute(self.conn)?;
delete(
proposed_node_endpoint::table
.filter(proposed_node_endpoint::circuit_id.eq(proposal.circuit_id())),
)
.execute(self.conn)?;
delete(
proposed_service::table
.filter(proposed_service::circuit_id.eq(proposal.circuit_id())),
)
.execute(self.conn)?;
delete(
proposed_service_argument::table
.filter(proposed_service_argument::circuit_id.eq(proposal.circuit_id())),
)
.execute(self.conn)?;
delete(vote_record::table.filter(vote_record::circuit_id.eq(proposal.circuit_id())))
.execute(self.conn)?;
let proposed_members: Vec<ProposedNodeModel> = Vec::try_from(proposal.circuit())?;
insert_into(proposed_node::table)
.values(proposed_members)
.execute(self.conn)?;
let proposed_member_endpoints: Vec<ProposedNodeEndpointModel> =
Vec::try_from(proposal.circuit())?;
insert_into(proposed_node_endpoint::table)
.values(proposed_member_endpoints)
.execute(self.conn)?;
let proposed_service: Vec<ProposedServiceModel> = Vec::try_from(proposal.circuit())?;
insert_into(proposed_service::table)
.values(proposed_service)
.execute(self.conn)?;
let proposed_service_argument: Vec<ProposedServiceArgumentModel> =
Vec::try_from(proposal.circuit())?;
insert_into(proposed_service_argument::table)
.values(proposed_service_argument)
.execute(self.conn)?;
let vote_record: Vec<VoteRecordModel> = Vec::try_from(&proposal)?;
insert_into(vote_record::table)
.values(vote_record)
.execute(self.conn)?;
Ok(())
})
}
}
#[cfg(feature = "sqlite")]
impl<'a> AdminServiceStoreUpdateProposalOperation
for AdminServiceStoreOperations<'a, diesel::sqlite::SqliteConnection>
{
fn update_proposal(&self, proposal: CircuitProposal) -> Result<(), AdminServiceStoreError> {
self.conn.transaction::<(), _, _>(|| {
circuit_proposal::table
.filter(circuit_proposal::circuit_id.eq(proposal.circuit_id()))
.first::<CircuitProposalModel>(self.conn)
.optional()?
.ok_or_else(|| {
AdminServiceStoreError::InvalidStateError(InvalidStateError::with_message(
String::from("CircuitProposal does not exist in AdminServiceStore"),
))
})?;
let proposal_model = CircuitProposalModel::from(&proposal);
update(circuit_proposal::table.find(proposal.circuit_id()))
.set((
circuit_proposal::proposal_type.eq(proposal_model.proposal_type),
circuit_proposal::circuit_hash.eq(proposal_model.circuit_hash),
circuit_proposal::requester.eq(proposal_model.requester),
circuit_proposal::requester_node_id.eq(proposal_model.requester_node_id),
))
.execute(self.conn)?;
let proposed_circuit_model = ProposedCircuitModel::from(proposal.circuit());
update(proposed_circuit::table.find(proposal.circuit_id()))
.set((
proposed_circuit::authorization_type
.eq(proposed_circuit_model.authorization_type),
proposed_circuit::persistence.eq(proposed_circuit_model.persistence),
proposed_circuit::durability.eq(proposed_circuit_model.durability),
proposed_circuit::routes.eq(proposed_circuit_model.routes),
proposed_circuit::circuit_management_type
.eq(proposed_circuit_model.circuit_management_type),
proposed_circuit::application_metadata
.eq(proposed_circuit_model.application_metadata),
proposed_circuit::comments.eq(proposed_circuit_model.comments),
))
.execute(self.conn)?;
delete(
proposed_node::table.filter(proposed_node::circuit_id.eq(proposal.circuit_id())),
)
.execute(self.conn)?;
delete(
proposed_node_endpoint::table
.filter(proposed_node_endpoint::circuit_id.eq(proposal.circuit_id())),
)
.execute(self.conn)?;
delete(
proposed_service::table
.filter(proposed_service::circuit_id.eq(proposal.circuit_id())),
)
.execute(self.conn)?;
delete(
proposed_service_argument::table
.filter(proposed_service_argument::circuit_id.eq(proposal.circuit_id())),
)
.execute(self.conn)?;
delete(vote_record::table.filter(vote_record::circuit_id.eq(proposal.circuit_id())))
.execute(self.conn)?;
let proposed_members: Vec<ProposedNodeModel> = Vec::try_from(proposal.circuit())?;
insert_into(proposed_node::table)
.values(proposed_members)
.execute(self.conn)?;
let proposed_member_endpoints: Vec<ProposedNodeEndpointModel> =
Vec::try_from(proposal.circuit())?;
insert_into(proposed_node_endpoint::table)
.values(proposed_member_endpoints)
.execute(self.conn)?;
let proposed_service: Vec<ProposedServiceModel> = Vec::try_from(proposal.circuit())?;
insert_into(proposed_service::table)
.values(proposed_service)
.execute(self.conn)?;
let proposed_service_argument: Vec<ProposedServiceArgumentModel> =
Vec::try_from(proposal.circuit())?;
insert_into(proposed_service_argument::table)
.values(proposed_service_argument)
.execute(self.conn)?;
let vote_record: Vec<VoteRecordModel> = Vec::try_from(&proposal)?;
insert_into(vote_record::table)
.values(vote_record)
.execute(self.conn)?;
Ok(())
})
}
}