mod builder;
pub use builder::QueryBuilder;
use crate::error::Result;
use crate::plan::{ActionPlan, DbActionPlan};
use postrust_sql::{SqlFragment, SqlParam};
pub fn build_query(plan: &ActionPlan, role: Option<&str>) -> Result<MainQuery> {
match plan {
ActionPlan::Db(db_plan) => build_db_query(db_plan, role),
ActionPlan::Info(_) => Ok(MainQuery::empty()),
}
}
fn build_db_query(plan: &DbActionPlan, role: Option<&str>) -> Result<MainQuery> {
let mut query = MainQuery::new();
if let Some(role) = role {
query.pre_statements.push(format!(
"SET LOCAL ROLE {}",
postrust_sql::escape_ident(role)
));
}
match plan {
DbActionPlan::Read(read_tree) => {
query.main = QueryBuilder::build_read(read_tree)?;
}
DbActionPlan::MutateRead { mutate, read } => {
query.main = QueryBuilder::build_mutate(mutate)?;
if let Some(read_tree) = read {
query.read = Some(QueryBuilder::build_read(read_tree)?);
}
}
DbActionPlan::Call { call, read } => {
query.main = QueryBuilder::build_call(call)?;
if let Some(read_tree) = read {
query.read = Some(QueryBuilder::build_read(read_tree)?);
}
}
}
Ok(query)
}
#[derive(Clone, Debug, Default)]
pub struct MainQuery {
pub pre_statements: Vec<String>,
pub main: SqlFragment,
pub read: Option<SqlFragment>,
pub count: Option<SqlFragment>,
}
impl MainQuery {
pub fn new() -> Self {
Self::default()
}
pub fn empty() -> Self {
Self::default()
}
pub fn has_main(&self) -> bool {
!self.main.is_empty()
}
pub fn build_main(self) -> (String, Vec<SqlParam>) {
self.main.build()
}
}