1use serde_json::{json, Value};
4
5#[derive(Debug, Clone, PartialEq)]
7pub struct SqlStmt {
8 pub text: String,
10 pub params: Vec<Value>,
12 pub is_write: bool,
14 pub row_shape: Option<RowShape>,
16 pub returning: Vec<String>,
18}
19
20impl SqlStmt {
21 pub fn select(text: String, params: Vec<Value>, row_shape: RowShape) -> Self {
22 SqlStmt {
23 text,
24 params,
25 is_write: false,
26 row_shape: Some(row_shape),
27 returning: Vec::new(),
28 }
29 }
30
31 pub fn write(text: String, params: Vec<Value>) -> Self {
32 SqlStmt {
33 text,
34 params,
35 is_write: true,
36 row_shape: None,
37 returning: Vec::new(),
38 }
39 }
40
41 pub fn write_returning(text: String, params: Vec<Value>, row_shape: RowShape) -> Self {
44 SqlStmt {
45 text,
46 params,
47 is_write: true,
48 row_shape: Some(row_shape),
49 returning: Vec::new(),
50 }
51 }
52
53 pub fn to_value(&self) -> Value {
54 json!({
55 "text": self.text,
56 "params": self.params,
57 "isWrite": self.is_write,
58 "rowShape": self.row_shape.as_ref().map(|r| r.to_value()).unwrap_or(Value::Null),
59 "returning": self.returning,
60 })
61 }
62}
63
64#[derive(Debug, Clone, PartialEq)]
66pub struct RowShape {
67 pub columns: Vec<RowCol>,
70 pub present_alias: Option<String>,
75}
76
77#[derive(Debug, Clone, PartialEq)]
78pub struct RowCol {
79 pub alias: String,
80 pub json_path: Vec<String>,
81 pub is_array: bool,
83 pub one: bool,
85 pub ones: Vec<bool>,
88 pub sub_shape: Option<RowShape>,
90 pub always: bool,
94 pub is_bool: bool,
98 pub is_json: bool,
101}
102
103impl RowShape {
104 pub fn empty() -> Self {
105 RowShape {
106 columns: Vec::new(),
107 present_alias: None,
108 }
109 }
110
111 pub fn to_value(&self) -> Value {
112 let cols: Vec<Value> = self
113 .columns
114 .iter()
115 .map(|c| {
116 json!({
117 "alias": c.alias,
118 "path": c.json_path,
119 "isArray": c.is_array,
120 "one": c.one,
121 "ones": c.ones,
122 "subShape": c.sub_shape.as_ref().map(|s| s.to_value()).unwrap_or(Value::Null),
123 "always": c.always,
124 "bool": c.is_bool,
125 "json": c.is_json,
126 })
127 })
128 .collect();
129 json!({
130 "columns": cols,
131 "present": self.present_alias.clone().unwrap_or_default(),
132 })
133 }
134}
135
136impl RowCol {
137 pub fn scalar(alias: &str, path: &[&str]) -> Self {
138 RowCol {
139 alias: alias.to_string(),
140 json_path: path.iter().map(|s| s.to_string()).collect(),
141 is_array: false,
142 one: false,
143 ones: Vec::new(),
144 sub_shape: None,
145 always: false,
146 is_bool: false,
147 is_json: false,
148 }
149 }
150
151 pub fn scalar_bool(alias: &str, path: &[&str], is_bool: bool) -> Self {
153 let mut c = RowCol::scalar(alias, path);
154 c.is_bool = is_bool;
155 c
156 }
157
158 pub fn json(alias: &str, path: &[&str]) -> Self {
160 let mut c = RowCol::scalar(alias, path);
161 c.is_json = true;
162 c
163 }
164
165 pub fn computed(alias: &str, path: &[&str]) -> Self {
167 RowCol {
168 alias: alias.to_string(),
169 json_path: path.iter().map(|s| s.to_string()).collect(),
170 is_array: false,
171 one: false,
172 ones: Vec::new(),
173 sub_shape: None,
174 always: true,
175 is_bool: false,
176 is_json: false,
177 }
178 }
179
180 pub fn array(alias: &str, sub_shape: RowShape) -> Self {
181 RowCol {
182 alias: alias.to_string(),
183 json_path: vec![alias.to_string()],
184 is_array: true,
185 one: false,
186 ones: vec![false],
187 sub_shape: Some(sub_shape),
188 always: false,
189 is_bool: false,
190 is_json: false,
191 }
192 }
193}