use crate::ast::{
Action, Cage, CageKind, Condition, Distance, Expr, GroupByMode, IndexDef, Join, LockMode,
LogicalOp, Operator, OverridingKind, SampleMethod, SetOp, TableConstraint, Value,
};
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct Qail {
pub action: Action,
pub table: String,
pub columns: Vec<Expr>,
pub joins: Vec<Join>,
pub cages: Vec<Cage>,
pub distinct: bool,
pub index_def: Option<IndexDef>,
pub table_constraints: Vec<TableConstraint>,
pub set_ops: Vec<(SetOp, Box<Qail>)>,
pub having: Vec<Condition>,
pub group_by_mode: GroupByMode,
pub ctes: Vec<CTEDef>,
pub distinct_on: Vec<Expr>,
pub returning: Option<Vec<Expr>>,
pub on_conflict: Option<OnConflict>,
pub source_query: Option<Box<Qail>>,
pub channel: Option<String>,
pub payload: Option<String>,
pub savepoint_name: Option<String>,
pub from_tables: Vec<String>,
pub using_tables: Vec<String>,
pub lock_mode: Option<LockMode>,
pub skip_locked: bool,
pub fetch: Option<(u64, bool)>,
pub default_values: bool,
pub overriding: Option<OverridingKind>,
pub sample: Option<(SampleMethod, f64, Option<u64>)>,
pub only_table: bool,
pub vector: Option<Vec<f32>>,
pub score_threshold: Option<f32>,
pub vector_name: Option<String>,
pub with_vector: bool,
pub vector_size: Option<u64>,
pub distance: Option<Distance>,
pub on_disk: Option<bool>,
pub function_def: Option<crate::ast::FunctionDef>,
pub trigger_def: Option<crate::ast::TriggerDef>,
pub policy_def: Option<crate::migrate::policy::RlsPolicy>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct CTEDef {
pub name: String,
pub recursive: bool,
pub columns: Vec<String>,
pub base_query: Box<Qail>,
pub recursive_query: Option<Box<Qail>>,
pub source_table: Option<String>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct OnConflict {
pub columns: Vec<String>,
pub action: ConflictAction,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum ConflictAction {
DoNothing,
DoUpdate {
assignments: Vec<(String, Expr)>,
},
}
impl Default for OnConflict {
fn default() -> Self {
Self {
columns: vec![],
action: ConflictAction::DoNothing,
}
}
}
impl ConflictAction {
pub(crate) fn update_assignments(&self) -> Option<&[(String, Expr)]> {
match self {
Self::DoNothing => None,
Self::DoUpdate { assignments } => Some(assignments),
}
}
}
impl Default for Qail {
fn default() -> Self {
Self {
action: Action::Get,
table: String::new(),
columns: vec![],
joins: vec![],
cages: vec![],
distinct: false,
index_def: None,
table_constraints: vec![],
set_ops: vec![],
having: vec![],
group_by_mode: GroupByMode::Simple,
ctes: vec![],
distinct_on: vec![],
returning: None,
on_conflict: None,
source_query: None,
channel: None,
payload: None,
savepoint_name: None,
from_tables: vec![],
using_tables: vec![],
lock_mode: None,
skip_locked: false,
fetch: None,
default_values: false,
overriding: None,
sample: None,
only_table: false,
vector: None,
score_threshold: None,
vector_name: None,
with_vector: false,
vector_size: None,
distance: None,
on_disk: None,
function_def: None,
trigger_def: None,
policy_def: None,
}
}
}
mod advanced;
mod constructors;
mod cte;
mod query;
mod rls;
mod vector;
impl Qail {
#[deprecated(since = "0.11.0", note = "Use .columns([...]) instead")]
pub fn hook(mut self, cols: &[&str]) -> Self {
self.columns = cols.iter().map(|c| Expr::Named(c.to_string())).collect();
self
}
#[deprecated(
since = "0.11.0",
note = "Use .filter(column, Operator::Eq, value) or .where_eq(column, value) instead"
)]
pub fn cage(mut self, column: &str, value: impl Into<Value>) -> Self {
self.cages.push(Cage {
kind: CageKind::Filter,
conditions: vec![Condition {
left: Expr::Named(column.to_string()),
op: Operator::Eq,
value: value.into(),
is_array_unnest: false,
}],
logical_op: LogicalOp::And,
});
self
}
}
impl std::fmt::Display for Qail {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use crate::fmt::Formatter;
match Formatter::new().format(self) {
Ok(s) => write!(f, "{}", s),
Err(_) => write!(f, "{:?}", self), }
}
}