use std::convert::TryFrom;
use diesel::{dsl::insert_into, 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::{ConstraintViolationError, ConstraintViolationType};
pub(in crate::admin::store::diesel) trait AdminServiceStoreAddProposalOperation {
fn add_proposal(&self, proposal: CircuitProposal) -> Result<(), AdminServiceStoreError>;
}
#[cfg(feature = "postgres")]
impl<'a> AdminServiceStoreAddProposalOperation
for AdminServiceStoreOperations<'a, diesel::pg::PgConnection>
{
fn add_proposal(&self, proposal: CircuitProposal) -> Result<(), AdminServiceStoreError> {
self.conn.transaction::<(), _, _>(|| {
if circuit_proposal::table
.filter(circuit_proposal::circuit_id.eq(proposal.circuit_id()))
.first::<CircuitProposalModel>(self.conn)
.optional()?
.is_some()
{
return Err(AdminServiceStoreError::ConstraintViolationError(
ConstraintViolationError::with_violation_type(ConstraintViolationType::Unique),
));
}
let circuit_proposal_model = CircuitProposalModel::from(&proposal);
insert_into(circuit_proposal::table)
.values(circuit_proposal_model)
.execute(self.conn)?;
let proposed_circuit_model = ProposedCircuitModel::from(proposal.circuit());
insert_into(proposed_circuit::table)
.values(proposed_circuit_model)
.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_services: Vec<ProposedServiceModel> = Vec::try_from(proposal.circuit())?;
insert_into(proposed_service::table)
.values(proposed_services)
.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_records: Vec<VoteRecordModel> = Vec::try_from(&proposal)?;
insert_into(vote_record::table)
.values(vote_records)
.execute(self.conn)?;
Ok(())
})
}
}
#[cfg(feature = "sqlite")]
impl<'a> AdminServiceStoreAddProposalOperation
for AdminServiceStoreOperations<'a, diesel::sqlite::SqliteConnection>
{
fn add_proposal(&self, proposal: CircuitProposal) -> Result<(), AdminServiceStoreError> {
self.conn.transaction::<(), _, _>(|| {
if circuit_proposal::table
.filter(circuit_proposal::circuit_id.eq(proposal.circuit_id()))
.first::<CircuitProposalModel>(self.conn)
.optional()?
.is_some()
{
return Err(AdminServiceStoreError::ConstraintViolationError(
ConstraintViolationError::with_violation_type(ConstraintViolationType::Unique),
));
}
let circuit_proposal_model = CircuitProposalModel::from(&proposal);
insert_into(circuit_proposal::table)
.values(circuit_proposal_model)
.execute(self.conn)?;
let proposed_circuit_model = ProposedCircuitModel::from(proposal.circuit());
insert_into(proposed_circuit::table)
.values(proposed_circuit_model)
.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_services: Vec<ProposedServiceModel> = Vec::try_from(proposal.circuit())?;
insert_into(proposed_service::table)
.values(proposed_services)
.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_records: Vec<VoteRecordModel> = Vec::try_from(&proposal)?;
insert_into(vote_record::table)
.values(vote_records)
.execute(self.conn)?;
Ok(())
})
}
}