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 },
107 Validated {
109 errors: Vec<String>,
110 },
111 Ok {},
112 Result {
114 columns: Vec<String>,
115 },
116 ResultEnd {
117 rows: u64,
118 },
119 NoResult {
120 #[serde(default, skip_serializing_if = "Option::is_none")]
121 rows_affected: Option<u64>,
122 },
123 Written {
124 files: Vec<String>,
125 #[serde(default, skip_serializing_if = "Vec::is_empty")]
127 warnings: Vec<String>,
128 },
129 Delivered {
130 location: String,
131 },
132 Loaded {
135 relation: String,
136 rows: u64,
137 #[serde(default, skip_serializing_if = "Option::is_none")]
138 warning: Option<String>,
139 },
140 Error {
141 message: String,
142 },
143}
144
145#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
147pub struct DeliveryFile {
148 pub local_path: String,
149 #[serde(default, skip_serializing_if = "Option::is_none")]
150 pub remote_path: Option<String>,
151}
152
153#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
155pub struct ResultSetMeta {
156 pub name: String,
158 pub query: String,
160 pub result_index: usize,
162 #[serde(default, skip_serializing_if = "Option::is_none")]
163 pub anchor: Option<String>,
164 #[serde(default, skip_serializing_if = "Option::is_none")]
165 pub header: Option<bool>,
166 #[serde(default, skip_serializing_if = "std::collections::BTreeMap::is_empty")]
168 pub columns: std::collections::BTreeMap<String, ColumnOptions>,
169}
170
171#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
173pub struct ColumnOptions {
174 #[serde(default, skip_serializing_if = "Option::is_none")]
176 pub format: Option<String>,
177 #[serde(default, skip_serializing_if = "Option::is_none")]
180 pub formula: Option<String>,
181 #[serde(default, skip_serializing_if = "Option::is_none")]
184 pub total: Option<String>,
185}
186
187#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
188pub struct ConnectionField {
189 pub name: String,
190 #[serde(default)]
191 pub description: String,
192 #[serde(default)]
193 pub required: bool,
194 #[serde(default)]
196 pub secret: bool,
197 #[serde(default, skip_serializing_if = "Option::is_none")]
198 pub default: Option<Value>,
199 #[serde(default, skip_serializing_if = "Option::is_none")]
202 pub same_as_source: Option<String>,
203}
204
205impl ConnectionField {
206 pub fn new(name: &str, description: &str) -> Self {
207 ConnectionField {
208 name: name.into(),
209 description: description.into(),
210 required: false,
211 secret: false,
212 default: None,
213 same_as_source: None,
214 }
215 }
216 pub fn required(mut self) -> Self {
217 self.required = true;
218 self
219 }
220 pub fn secret(mut self) -> Self {
221 self.secret = true;
222 self
223 }
224 pub fn default(mut self, v: impl Into<Value>) -> Self {
225 self.default = Some(v.into());
226 self
227 }
228 pub fn same_as_source(mut self, source_type: &str) -> Self {
229 self.same_as_source = Some(source_type.into());
230 self
231 }
232}