use crate::api_request::types::{FieldName, Payload};
use crate::types::identifiers::QualifiedIdentifier;
use super::types::*;
#[derive(Debug, Clone)]
pub enum MutatePlan {
Insert(InsertPlan),
Update(UpdatePlan),
Delete(DeletePlan),
}
impl MutatePlan {
pub fn qi(&self) -> &QualifiedIdentifier {
match self {
MutatePlan::Insert(p) => &p.into,
MutatePlan::Update(p) => &p.into,
MutatePlan::Delete(p) => &p.from,
}
}
pub fn returning(&self) -> &[CoercibleSelectField] {
match self {
MutatePlan::Insert(p) => &p.returning,
MutatePlan::Update(p) => &p.returning,
MutatePlan::Delete(p) => &p.returning,
}
}
}
#[derive(Debug, Clone)]
pub struct InsertPlan {
pub into: QualifiedIdentifier,
pub columns: Vec<CoercibleField>,
pub body: Payload,
pub on_conflict: Option<OnConflict>,
pub where_: Vec<CoercibleLogicTree>,
pub returning: Vec<CoercibleSelectField>,
pub pk_cols: Vec<FieldName>,
pub apply_defaults: bool,
}
#[derive(Debug, Clone)]
pub struct UpdatePlan {
pub into: QualifiedIdentifier,
pub columns: Vec<CoercibleField>,
pub body: Payload,
pub where_: Vec<CoercibleLogicTree>,
pub returning: Vec<CoercibleSelectField>,
pub apply_defaults: bool,
}
#[derive(Debug, Clone)]
pub struct DeletePlan {
pub from: QualifiedIdentifier,
pub where_: Vec<CoercibleLogicTree>,
pub returning: Vec<CoercibleSelectField>,
}
#[derive(Debug, Clone)]
pub struct OnConflict {
pub columns: Vec<FieldName>,
pub merge_duplicates: bool,
}
#[cfg(test)]
mod tests {
use super::*;
fn test_qi(name: &str) -> QualifiedIdentifier {
QualifiedIdentifier::new("public", name)
}
#[test]
fn test_mutate_plan_qi() {
let insert = MutatePlan::Insert(InsertPlan {
into: test_qi("users"),
columns: vec![],
body: Payload::RawJSON(bytes::Bytes::new()),
on_conflict: None,
where_: vec![],
returning: vec![],
pk_cols: vec![],
apply_defaults: false,
});
assert_eq!(insert.qi().name.as_str(), "users");
let update = MutatePlan::Update(UpdatePlan {
into: test_qi("posts"),
columns: vec![],
body: Payload::RawJSON(bytes::Bytes::new()),
where_: vec![],
returning: vec![],
apply_defaults: false,
});
assert_eq!(update.qi().name.as_str(), "posts");
let delete = MutatePlan::Delete(DeletePlan {
from: test_qi("comments"),
where_: vec![],
returning: vec![],
});
assert_eq!(delete.qi().name.as_str(), "comments");
}
#[test]
fn test_on_conflict() {
let oc = OnConflict {
columns: vec!["id".into()],
merge_duplicates: true,
};
assert!(oc.merge_duplicates);
assert_eq!(oc.columns.len(), 1);
}
#[test]
fn test_insert_plan_with_on_conflict() {
let plan = InsertPlan {
into: test_qi("users"),
columns: vec![],
body: Payload::RawJSON(bytes::Bytes::from("{}")),
on_conflict: Some(OnConflict {
columns: vec!["id".into()],
merge_duplicates: true,
}),
where_: vec![],
returning: vec![],
pk_cols: vec!["id".into()],
apply_defaults: true,
};
assert!(plan.on_conflict.is_some());
assert!(plan.apply_defaults);
assert_eq!(plan.pk_cols.len(), 1);
}
}