use sqlx::PgPool;
use tracing::instrument;
use crate::primitives::{AccountId, VelocityControlId};
use super::{super::error::*, value::*};
#[derive(Debug, Clone)]
pub struct AccountControlRepo {
_pool: PgPool,
}
impl AccountControlRepo {
pub fn new(pool: &PgPool) -> Self {
Self {
_pool: pool.clone(),
}
}
#[instrument(
level = "debug",
name = "account_control.create_in_op",
skip_all,
err(level = "warn")
)]
pub async fn create_in_op(
&self,
op: &mut impl es_entity::AtomicOperation,
control: AccountVelocityControl,
) -> Result<(), VelocityError> {
sqlx::query!(
r#"INSERT INTO cala_velocity_account_controls (account_id, velocity_control_id, values)
VALUES ($1, $2, $3)"#,
control.account_id as AccountId,
control.control_id as VelocityControlId,
serde_json::to_value(control).expect("Failed to serialize control values"),
)
.execute(op.as_executor())
.await?;
Ok(())
}
#[instrument(
level = "debug",
name = "account_control.create_all_in_op",
skip_all,
fields(count = controls.len()),
err(level = "warn")
)]
pub async fn create_all_in_op(
&self,
op: &mut impl es_entity::AtomicOperation,
mut controls: Vec<AccountVelocityControl>,
) -> Result<(), VelocityError> {
if controls.is_empty() {
return Ok(());
}
controls.sort_unstable_by_key(|c| c.account_id);
let mut account_ids = Vec::with_capacity(controls.len());
let mut control_ids = Vec::with_capacity(controls.len());
let mut values = Vec::with_capacity(controls.len());
for control in controls {
account_ids.push(control.account_id);
control_ids.push(control.control_id);
values.push(serde_json::to_value(control).expect("Failed to serialize control values"));
}
sqlx::query!(
r#"
INSERT INTO cala_velocity_account_controls (account_id, velocity_control_id, values)
SELECT account_id, velocity_control_id, values
FROM UNNEST($1::uuid[], $2::uuid[], $3::jsonb[])
AS v(account_id, velocity_control_id, values)
"#,
&account_ids as &[AccountId],
&control_ids as &[VelocityControlId],
&values,
)
.execute(op.as_executor())
.await?;
Ok(())
}
}