1
2use serde::{Deserialize, Deserializer, Serialize};
3use serde_json::{ Value as JsonValue};
4use std::path::PathBuf;
5use crate::DatabaseKind;
6
7
8#[derive(Debug, Serialize, Deserialize, Clone)]
9pub struct OthersRes<T> {
10 pub rows_affected: u64,
11 pub sql: Option<String>,
12 pub results: Option<Vec<T>>,
13}
14impl<T> Default for OthersRes<T> {
15 fn default() -> Self {
16 Self {
17 rows_affected: 0,
18 results: None,
19 sql: None,
20 }
21 }
22}
23impl<T> OthersRes<T> {
24 pub fn new(rows_affected: u64) -> Self {
25 Self {
26 rows_affected,
27 results: None,
28 sql: None,
29 }
30 }
31 pub fn with(data: Vec<T>, rows_affected: usize) -> Self {
32 Self {
33 rows_affected: rows_affected as u64,
34 results: Some(data),
35 sql: None,
36 }
37 }
38}
39
40#[derive(Debug, Serialize, Deserialize, Clone)]
41pub struct ColumnBaseInfo {
42 pub name: String,
43 #[serde(rename = "type")]
44 pub r#type: String,
45 pub index: u64,
46}
47
48#[derive(Debug, Serialize, Deserialize, Clone)]
49pub struct SelectRes<T> {
50 pub results: Vec<T>,
51 pub length: usize,
52 pub count: usize,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub sql: Option<String>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub columns: Option<Vec<ColumnBaseInfo>>,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub table_name: Option<String>,
59}
60impl<T> Default for SelectRes<T> {
61 fn default() -> Self {
62 Self {
63 results: Vec::new(),
64 length: 0,
65 count: 0,
66 sql: None,
67 columns: None,
68 table_name: None,
69 }
70 }
71}
72impl<T> SelectRes<T> {
73 pub fn new(
74 results: Vec<T>,
75 count: usize,
76 columns: Option<Vec<ColumnBaseInfo>>,
77 sql: Option<String>,
78 ) -> Self {
79 let length = results.len();
80 Self {
81 results,
82 length,
83 count,
84 sql,
85 columns,
86 table_name: None,
87 }
88 }
89}
90
91#[derive(Debug, Serialize, Deserialize, Clone, Default)]
92pub struct SqlRespone {
93 pub length: u64, pub rows_affected: u64, pub count: u64,
96 pub results: Option<Vec<JsonValue>>, pub columns: Option<Vec<ColumnBaseInfo>>,
98 pub is_query: bool,
99 pub sql: Option<String>,
100 pub table_name: Option<String>,
101}
102
103#[derive(Debug)]
104#[cfg_attr(any(feature = "postgres", feature = "mysql", feature = "sqlite"), derive(sqlx::FromRow))]
105pub struct DataCount {
106 pub count: u32,
107}
108
109#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
110#[cfg_attr(any(feature = "postgres", feature = "mysql", feature = "sqlite"), derive(sqlx::FromRow))]
111pub struct TableColumn {
112 pub name: String,
113 pub ordinal_position: i32, #[serde(rename = "type")]
115 pub r#type: String,
116 pub base_type: Option<String>, pub foreign_key_table: Option<String>, pub foreign_key_column: Option<String>, #[serde(deserialize_with = "bool_or_int_to_bool")]
121 pub auto_increment: bool, #[serde(deserialize_with = "bool_or_int_to_bool")]
123 pub not_null: bool, pub dflt_value: Option<String>, #[serde(deserialize_with = "bool_or_int_to_bool")]
126 pub pk: bool, pub index_name: Option<String>, #[serde(deserialize_with = "bool_or_int_to_bool")]
129 pub non_unique: bool, pub description: Option<String>, }
132
133fn bool_or_int_to_bool<'de, D>(deserializer: D) -> std::result::Result<bool, D::Error>
134where
135 D: Deserializer<'de>,
136{
137 let v = JsonValue::deserialize(deserializer)?;
139 match v {
141 JsonValue::Bool(b) => Ok(b), JsonValue::Number(n) => {
143 if let Some(i) = n.as_i64() {
145 match i {
146 1 => Ok(true),
147 0 => Ok(false),
148 _ => Err(serde::de::Error::invalid_value(
149 serde::de::Unexpected::Signed(i),
150 &"expected 1 or 0 for boolean value",
151 )),
152 }
153 } else {
154 Err(serde::de::Error::invalid_type(
155 serde::de::Unexpected::Other("non-integer number"),
156 &"expected integer 1 or 0 for boolean value",
157 ))
158 }
159 }
160 _ => Err(serde::de::Error::invalid_type(
161 serde::de::Unexpected::Other("unexpected value"),
162 &"expected boolean or integer 1/0",
163 )),
164 }
165}
166#[derive(Debug, Serialize, Deserialize, Clone)]
169pub struct DbConnect {
170 pub kind: DatabaseKind,
171 #[serde(default = "DbConnect::default_empty")]
172 pub host: String,
173 pub port: i64,
174 #[serde(default = "DbConnect::default_empty")]
175 pub username: String,
176 #[serde(default = "DbConnect::default_empty")]
177 pub password: String,
178 #[serde(default = "DbConnect::default_empty")]
179 pub db_name: String,
180 #[serde(default = "DbConnect::default_empty")]
181 pub charset: String,
182 pub ssl_mode: Option<String>,
183 pub ca_cert: Option<String>,
184 pub client_cert: Option<String>,
185 pub client_key: Option<String>,
186 pub max_connections: Option<i64>,
187 pub min_connections: Option<i64>,
188 pub timeout: Option<i64>,
189 pub service_name: Option<String>,
190 pub instance: Option<String>,
191
192 pub file_dir: PathBuf,
193 pub file_path: PathBuf,
194 pub http: Option<String>,
195 pub region: Option<String>,
196 pub api: Option<String>,
197 pub api_token: Option<String>,
198}
199
200impl Default for DbConnect {
201 fn default() -> Self {
202 Self {
203 kind: DatabaseKind::Postgres,
204 host: "127.0.0.1".to_string(),
205 port: 5432,
206 username: "postgres".to_string(),
207 password: "postgres".to_string(),
208 db_name: "".to_string(),
209 charset: "".to_string(),
210 ssl_mode: None,
211 ca_cert: None,
212 client_cert: None,
213 client_key: None,
214 max_connections: None,
215 min_connections: None,
216 timeout: None,
217 service_name: None,
218 instance: None,
219 file_dir: PathBuf::new(),
220 file_path: PathBuf::new(),
221 http: None,
222 region: None,
223 api: None,
224 api_token: None,
225 }
226 }
227}
228
229impl DbConnect {
230 fn default_empty() -> String {
231 String::new()
232 }
233 pub fn merge_with_changes(&mut self, new_connect: &DbConnect) -> bool {
235 let mut changed = false;
236 if self.host != new_connect.host {
237 self.host = new_connect.host.clone();
238 changed = true
239 }
240 if self.port != new_connect.port {
241 self.port = new_connect.port;
242 changed = true
243 }
244 if self.username != new_connect.username {
245 self.username = new_connect.username.clone();
246 changed = true
247 }
248 if self.password != new_connect.password {
249 self.password = new_connect.password.clone();
250 changed = true
251 }
252 if self.db_name != new_connect.db_name {
253 self.db_name = new_connect.db_name.clone();
254 changed = true
255 }
256 if self.charset != new_connect.charset {
257 self.charset = new_connect.charset.clone();
258 changed = true
259 }
260 if self.file_path != new_connect.file_path {
261 self.file_path = new_connect.file_path.clone();
262 changed = true
263 }
264 if self.file_dir != new_connect.file_dir {
265 self.file_dir = new_connect.file_dir.clone();
266 changed = true
267 }
268 if self.api != new_connect.api {
269 self.api = new_connect.api.clone();
270 changed = true
271 }
272 if self.http != new_connect.http {
273 self.http = new_connect.http.clone();
274 changed = true
275 }
276 changed
278 }
279}
280
281#[derive(Serialize, Debug, Deserialize, PartialEq, Eq, Clone)]
282pub struct SchemaInfo {
283 pub name: String,
284 pub tables: Vec<TableInfo>,
285}
286#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
287#[cfg_attr(any(feature = "postgres", feature = "mysql", feature = "sqlite"), derive(sqlx::FromRow))]
288pub struct DatabaseInfo {
289 pub db_name: String,
290 pub tables: Vec<TableInfo>,
291 pub schemas: Vec<SchemaInfo>,
292}
293
294#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
295pub struct TableInfo {
296 pub table_name: String, #[serde(skip_serializing_if = "Option::is_none")]
298 pub table_comment: Option<String>,
299 pub columns: Vec<TableColumn>, pub create_sql: String,
301}