use serde_json::{json, Value};
#[derive(Debug, Clone, PartialEq)]
pub struct SqlStmt {
pub text: String,
pub params: Vec<Value>,
pub is_write: bool,
pub row_shape: Option<RowShape>,
pub returning: Vec<String>,
}
impl SqlStmt {
pub fn select(text: String, params: Vec<Value>, row_shape: RowShape) -> Self {
SqlStmt {
text,
params,
is_write: false,
row_shape: Some(row_shape),
returning: Vec::new(),
}
}
pub fn write(text: String, params: Vec<Value>) -> Self {
SqlStmt {
text,
params,
is_write: true,
row_shape: None,
returning: Vec::new(),
}
}
pub fn to_value(&self) -> Value {
json!({
"text": self.text,
"params": self.params,
"isWrite": self.is_write,
"rowShape": self.row_shape.as_ref().map(|r| r.to_value()).unwrap_or(Value::Null),
"returning": self.returning,
})
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct RowShape {
pub columns: Vec<RowCol>,
pub present_alias: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RowCol {
pub alias: String,
pub json_path: Vec<String>,
pub is_array: bool,
pub one: bool,
pub ones: Vec<bool>,
pub sub_shape: Option<RowShape>,
pub always: bool,
pub is_bool: bool,
pub is_json: bool,
}
impl RowShape {
pub fn empty() -> Self {
RowShape {
columns: Vec::new(),
present_alias: None,
}
}
pub fn to_value(&self) -> Value {
let cols: Vec<Value> = self
.columns
.iter()
.map(|c| {
json!({
"alias": c.alias,
"path": c.json_path,
"isArray": c.is_array,
"one": c.one,
"ones": c.ones,
"subShape": c.sub_shape.as_ref().map(|s| s.to_value()).unwrap_or(Value::Null),
"always": c.always,
"bool": c.is_bool,
"json": c.is_json,
})
})
.collect();
json!({
"columns": cols,
"present": self.present_alias.clone().unwrap_or_default(),
})
}
}
impl RowCol {
pub fn scalar(alias: &str, path: &[&str]) -> Self {
RowCol {
alias: alias.to_string(),
json_path: path.iter().map(|s| s.to_string()).collect(),
is_array: false,
one: false,
ones: Vec::new(),
sub_shape: None,
always: false,
is_bool: false,
is_json: false,
}
}
pub fn scalar_bool(alias: &str, path: &[&str], is_bool: bool) -> Self {
let mut c = RowCol::scalar(alias, path);
c.is_bool = is_bool;
c
}
pub fn json(alias: &str, path: &[&str]) -> Self {
let mut c = RowCol::scalar(alias, path);
c.is_json = true;
c
}
pub fn computed(alias: &str, path: &[&str]) -> Self {
RowCol {
alias: alias.to_string(),
json_path: path.iter().map(|s| s.to_string()).collect(),
is_array: false,
one: false,
ones: Vec::new(),
sub_shape: None,
always: true,
is_bool: false,
is_json: false,
}
}
pub fn array(alias: &str, sub_shape: RowShape) -> Self {
RowCol {
alias: alias.to_string(),
json_path: vec![alias.to_string()],
is_array: true,
one: false,
ones: vec![false],
sub_shape: Some(sub_shape),
always: false,
is_bool: false,
is_json: false,
}
}
}