use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum NativeQueryKind {
Select,
Crosstab,
Delete,
Update,
Append,
MakeTable,
DataDefinition,
Passthrough,
Union,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NativeQueryColumn {
pub table: Option<String>,
pub field: Option<String>,
pub expression: Option<String>,
pub descending: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum NativeJoinKind {
Inner,
Left,
Right,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NativeJoin {
pub expression: String,
pub kind: NativeJoinKind,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NativeOrder {
pub field: String,
pub descending: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NativeQuery {
pub name: String,
pub kind: NativeQueryKind,
pub tables: Vec<String>,
pub columns: Vec<NativeQueryColumn>,
pub criteria: Vec<String>,
#[serde(default)]
pub group_by: Vec<String>,
#[serde(default)]
pub having: Vec<String>,
pub joins: Vec<NativeJoin>,
pub order_by: Vec<NativeOrder>,
#[serde(default)]
pub select_flags: i64,
#[serde(default)]
pub parameters: Vec<String>,
}
impl NativeQuery {
pub fn query_def(&self) -> Option<crate::qbe::QueryDef> {
if self.kind != NativeQueryKind::Select
|| self.tables.len() != 1
|| !self.criteria.is_empty()
|| !self.group_by.is_empty()
|| !self.having.is_empty()
|| !self.joins.is_empty()
{
return None;
}
let mut fields = Vec::with_capacity(self.columns.len());
for column in &self.columns {
if column.expression.is_some() {
return None;
}
let field = column.field.as_ref()?;
fields.push(crate::qbe::QbeField {
name: field.clone(),
shown: true,
sort: if column.descending {
crate::qbe::SortOrder::Descending
} else {
crate::qbe::SortOrder::Ascending
},
criteria: Vec::new(),
});
}
Some(crate::qbe::QueryDef {
name: self.name.clone(),
table: self.tables[0].clone(),
fields,
})
}
}