1use serde::{Deserialize, Serialize};
4use serde_json::{Map, Value};
5
6pub use crate::options::OptionField;
7use crate::{Kind, PluginId};
8
9#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11#[serde(tag = "type", rename_all = "snake_case")]
12pub enum Request {
13 Hello {
15 min_version: u32,
16 max_version: u32,
17 core_version: String,
18 #[serde(default, skip_serializing_if = "Option::is_none")]
21 plugin: Option<PluginId>,
22 },
23 Describe {},
26 Validate {
29 options: Map<String, Value>,
30 },
31 Open {
33 connection: Map<String, Value>,
34 read_only: bool,
35 },
36 Execute {
39 sql: String,
40 #[serde(default, skip_serializing_if = "Option::is_none")]
41 row_limit: Option<u64>,
42 },
43 Check {
45 sql: String,
46 },
47 Write {
50 path: String,
51 format: String,
52 options: Map<String, Value>,
53 result_sets: Vec<ResultSetMeta>,
54 #[serde(default, skip_serializing_if = "Option::is_none")]
55 template: Option<Value>,
56 },
57 ResultSetEnd {},
58 Finish {},
59 Deliver {
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 local_path: Option<String>,
65 #[serde(default, skip_serializing_if = "Option::is_none")]
66 remote_path: Option<String>,
67 #[serde(default, skip_serializing_if = "Vec::is_empty")]
68 files: Vec<DeliveryFile>,
69 connection: Map<String, Value>,
70 #[serde(default)]
71 options: Map<String, Value>,
72 },
73 Load {
77 name: String,
78 },
79 Close {},
81}
82
83#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
85#[serde(tag = "type", rename_all = "snake_case")]
86pub enum Response {
87 Hello {
88 protocol_version: u32,
89 kind: Kind,
90 name: String,
91 version: String,
92 #[serde(default)]
93 capabilities: Vec<String>,
94 #[serde(default, skip_serializing_if = "Vec::is_empty")]
96 provides: Vec<PluginId>,
97 },
98 VersionMismatch {
99 min_version: u32,
100 max_version: u32,
101 },
102 Describe {
103 connection_fields: Vec<ConnectionField>,
104 #[serde(default, skip_serializing_if = "Vec::is_empty")]
105 option_fields: Vec<OptionField>,
106 #[serde(default, skip_serializing_if = "Option::is_none")]
110 identifier_quote: Option<String>,
111 },
112 Validated {
114 errors: Vec<String>,
115 },
116 Ok {},
117 Result {
119 columns: Vec<String>,
120 },
121 ResultEnd {
122 rows: u64,
123 },
124 NoResult {
125 #[serde(default, skip_serializing_if = "Option::is_none")]
126 rows_affected: Option<u64>,
127 },
128 Written {
129 files: Vec<String>,
130 #[serde(default, skip_serializing_if = "Vec::is_empty")]
132 warnings: Vec<String>,
133 },
134 Delivered {
135 location: String,
136 },
137 Loaded {
140 relation: String,
141 rows: u64,
142 #[serde(default, skip_serializing_if = "Option::is_none")]
143 warning: Option<String>,
144 },
145 Error {
146 message: String,
147 },
148}
149
150#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
152pub struct DeliveryFile {
153 pub local_path: String,
154 #[serde(default, skip_serializing_if = "Option::is_none")]
155 pub remote_path: Option<String>,
156}
157
158#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
160pub struct ResultSetMeta {
161 pub name: String,
163 pub query: String,
165 pub result_index: usize,
167 #[serde(default, skip_serializing_if = "Option::is_none")]
168 pub anchor: Option<String>,
169 #[serde(default, skip_serializing_if = "Option::is_none")]
170 pub header: Option<bool>,
171 #[serde(default, skip_serializing_if = "std::collections::BTreeMap::is_empty")]
173 pub columns: std::collections::BTreeMap<String, ColumnOptions>,
174}
175
176#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
178pub struct ColumnOptions {
179 #[serde(default, skip_serializing_if = "Option::is_none")]
181 pub format: Option<String>,
182 #[serde(default, skip_serializing_if = "Option::is_none")]
185 pub formula: Option<String>,
186 #[serde(default, skip_serializing_if = "Option::is_none")]
189 pub total: Option<String>,
190}
191
192#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
193pub struct ConnectionField {
194 pub name: String,
195 #[serde(default)]
196 pub description: String,
197 #[serde(default)]
198 pub required: bool,
199 #[serde(default)]
201 pub secret: bool,
202 #[serde(default, skip_serializing_if = "Option::is_none")]
203 pub default: Option<Value>,
204 #[serde(default, skip_serializing_if = "Option::is_none")]
207 pub same_as_source: Option<String>,
208}
209
210impl ConnectionField {
211 pub fn new(name: &str, description: &str) -> Self {
212 ConnectionField {
213 name: name.into(),
214 description: description.into(),
215 required: false,
216 secret: false,
217 default: None,
218 same_as_source: None,
219 }
220 }
221 pub fn required(mut self) -> Self {
222 self.required = true;
223 self
224 }
225 pub fn secret(mut self) -> Self {
226 self.secret = true;
227 self
228 }
229 pub fn default(mut self, v: impl Into<Value>) -> Self {
230 self.default = Some(v.into());
231 self
232 }
233 pub fn same_as_source(mut self, source_type: &str) -> Self {
234 self.same_as_source = Some(source_type.into());
235 self
236 }
237}