1use json::{JsonValue, object};
2pub static DISABLE_FIELD: &[&str] = &["default", "select", "delete", "insert", "update", "order", "group", "user", "password", "desc", "index", "from", "host", "user", "read", "partition"];
3
4pub fn validate_table_name(name: &str) -> Result<&str, String> {
6 let name = name.trim();
7 if name.is_empty() {
8 return Err("表名不能为空".to_string());
9 }
10 if name.contains('\'') || name.contains(';') || name.contains('"') || name.contains('`') {
11 return Err(format!("表名包含非法字符: {}", name));
12 }
13 Ok(name)
14}
15
16pub fn add_table_prefix(prefix: &str, name: &str) -> String {
18 format!("{}{}", prefix, name)
19}
20
21#[cfg(feature = "db-sqlite")]
22pub mod sqlite;
23#[cfg(feature = "db-mysql")]
24pub mod mysql;
25#[cfg(feature = "db-mssql")]
26pub mod mssql;
27#[cfg(feature = "db-pgsql")]
28pub mod pgsql;
29
30pub trait DbMode {
31 fn database_tables(&mut self) -> JsonValue;
33 fn database_create(&mut self, name: &str) -> bool;
35 fn database_update(&mut self, _name: &str, _options: JsonValue) -> bool {
37 false }
39 fn backups(&mut self, _filename: &str) -> bool {
41 false
42 }
43}
44
45#[derive(Debug, Clone)]
46pub struct TableOptions {
47 table_name: String,
48 table_title: String,
49 table_key: String,
50 table_fields: JsonValue,
51 table_unique: Vec<String>,
52 table_index: Vec<Vec<String>>,
53 table_partition: bool,
54 table_partition_columns: JsonValue,
55}
56impl TableOptions {
57 pub fn set_table_name(&mut self, name: &str) {
58 self.table_name = name.to_string()
59 }
60 pub fn set_table_title(&mut self, name: &str) {
61 self.table_title = name.to_string()
62 }
63 pub fn set_table_key(&mut self, name: &str) {
64 self.table_key = name.to_string()
65 }
66 pub fn set_table_fields(&mut self, fields: JsonValue) {
67 self.table_fields = fields;
68 }
69 pub fn set_table_unique(&mut self, unique: Vec<&str>) {
70 self.table_unique = unique.iter().map(|s| s.to_string()).collect();
71 }
72 pub fn set_table_index(&mut self, index: Vec<Vec<&str>>) {
73 self.table_index = index.iter().map(|s| s.iter().map(|s| s.to_string()).collect()).collect();
74 }
75 pub fn set_table_partition(&mut self, index: bool) {
76 self.table_partition = index;
77 }
78 pub fn set_table_partition_columns(&mut self, index: JsonValue) {
79 self.table_partition_columns = index;
80 }
81}
82impl Default for TableOptions {
83 fn default() -> Self {
84 Self {
85 table_name: "".to_string(),
86 table_title: "".to_string(),
87 table_key: "".to_string(),
88 table_fields: JsonValue::Null,
89 table_unique: vec![],
90 table_index: vec![],
91 table_partition: false,
92 table_partition_columns: JsonValue::Null,
93 }
94 }
95}
96pub trait Mode: DbMode {
97 fn table_create(&mut self, options: TableOptions) -> JsonValue;
98 fn table_update(&mut self, options: TableOptions) -> JsonValue;
99 fn table_info(&mut self, table: &str) -> JsonValue;
101 fn table_is_exist(&mut self, name: &str) -> bool;
103 fn table(&mut self, name: &str) -> &mut Self;
105 fn change_table(&mut self, name: &str) -> &mut Self;
107
108 fn autoinc(&mut self) -> &mut Self;
110 fn fetch_sql(&mut self) -> &mut Self;
112 fn order(&mut self, field: &str, by: bool) -> &mut Self;
114 fn group(&mut self, field: &str) -> &mut Self;
116 fn distinct(&mut self) -> &mut Self;
118 fn json(&mut self, field: &str) -> &mut Self;
120 fn location(&mut self, field: &str) -> &mut Self;
122 fn field(&mut self, field: &str) -> &mut Self;
124 fn hidden(&mut self, name: &str) -> &mut Self;
126 fn where_and(&mut self, field: &str, compare: &str, value: JsonValue) -> &mut Self;
128 fn where_or(&mut self, field: &str, compare: &str, value: JsonValue) -> &mut Self;
129
130 fn where_column(&mut self, field_a: &str, compare: &str, field_b: &str) -> &mut Self;
132 fn update_column(&mut self, field_a: &str, compare: &str) -> &mut Self;
134 fn page(&mut self, page: i32, limit: i32) -> &mut Self;
136 fn column(&mut self, field: &str) -> JsonValue;
138 fn count(&mut self) -> JsonValue;
140 fn max(&mut self, field: &str) -> JsonValue;
142 fn min(&mut self, field: &str) -> JsonValue;
144 fn sum(&mut self, field: &str) -> JsonValue;
146 fn avg(&mut self, field: &str) -> JsonValue;
148 fn select(&mut self) -> JsonValue;
150 fn find(&mut self) -> JsonValue;
152 fn value(&mut self, field: &str) -> JsonValue;
154 fn insert(&mut self, data: JsonValue) -> JsonValue;
156 fn insert_all(&mut self, data: JsonValue) -> JsonValue;
158
159 fn update(&mut self, data: JsonValue) -> JsonValue;
161 fn update_all(&mut self, data: JsonValue) -> JsonValue;
163 fn delete(&mut self) -> JsonValue;
165
166 fn transaction(&mut self) -> bool;
168 fn commit(&mut self) -> bool;
170 fn rollback(&mut self) -> bool;
172 fn sql(&mut self, sql: &str) -> Result<JsonValue, String>;
174 fn sql_execute(&mut self, sql: &str) -> Result<JsonValue, String>;
175 fn inc(&mut self, field: &str, num: f64) -> &mut Self;
177 fn dec(&mut self, field: &str, num: f64) -> &mut Self;
179
180 fn buildsql(&mut self) -> String;
182
183 fn join_fields(&mut self, fields: Vec<&str>) -> &mut Self;
184 fn join(&mut self, main_table: &str, main_fields: &str, right_table: &str, right_fields: &str) -> &mut Self;
190
191 fn join_inner(&mut self, table: &str, main_fields: &str, second_fields: &str) -> &mut Self;
197}
198
199#[derive(Clone, Debug)]
200pub struct Params {
201 pub mode: String,
202 pub autoinc: bool,
203 pub table: String,
204 pub where_and: Vec<String>,
205 pub where_or: Vec<String>,
206 pub where_column: String,
207 pub update_column: Vec<String>,
208 pub inc_dec: JsonValue,
209 pub page: i32,
210 pub limit: i32,
211 pub fields: JsonValue,
212 pub top: String,
213 pub top2: String,
214 pub order: JsonValue,
215 pub group: JsonValue,
216 pub distinct: bool,
217 pub json: JsonValue,
218 pub location: JsonValue,
219 pub sql: bool,
220 pub join: Vec<String>,
221 pub join_inner: Vec<String>,
222 pub join_table: String,
223}
224
225impl Params {
226 pub fn default(mode: &str) -> Self {
227 Self {
228 mode: mode.to_string(),
229 autoinc: false,
230 table: "".to_string(),
231 where_and: vec![],
232 where_or: vec![],
233 where_column: "".to_string(),
234 update_column: vec![],
235 inc_dec: object! {},
236 page: -1,
237 limit: 10,
238 fields: object! {},
239 top: String::new(),
240 top2: String::new(),
241 order: object! {},
242 group: object! {},
243 distinct: false,
244 json: object! {},
245 location: object! {},
246 sql: false,
247 join: Vec::new(),
248 join_inner: Vec::new(),
249 join_table: "".to_string(),
250 }
251 }
252 pub fn where_sql(&mut self) -> String {
253 let mut where_and_sql = vec![];
254 let mut where_or_sql = vec![];
255 let mut sql = vec![];
256
257 for item in self.where_or.iter() {
258 where_or_sql.push(item.clone());
259 }
260 if !where_or_sql.is_empty() {
261 sql.push(format!(" ( {} ) ", where_or_sql.join(" OR ")));
262 }
263
264 for item in self.where_and.iter() {
265 where_and_sql.push(item.clone());
266 }
267 if !where_and_sql.is_empty() {
268 sql.push(where_and_sql.join(" AND "));
269 }
270
271 if !self.where_column.is_empty() {
272 sql.push(self.where_column.clone());
273 }
274
275 if !sql.is_empty() {
276 return format!("WHERE {}", sql.join(" AND "));
277 }
278 "".to_string()
279 }
280 pub fn page_limit_sql(&mut self) -> String {
281 if self.page == -1 {
282 return "".to_string();
283 }
284 match self.mode.as_str() {
285 "mysql" => {
286 format!("LIMIT {},{}", self.page * self.limit - self.limit, self.limit)
287 }
288 "sqlite" => {
289 format!("LIMIT {} OFFSET {}", self.limit, self.page * self.limit - self.limit)
290 }
291 _ => "".to_string()
292 }
293 }
294 pub fn fields(&mut self) -> String {
295 let mut fields = vec![];
296 for (_, value) in self.fields.entries() {
297 match self.mode.as_str() {
298 "mssql" => {
299 fields.push(format!("{value}"));
300 }
301 "mysql" => {
302 if DISABLE_FIELD.contains(&value.as_str().unwrap()) {
303 fields.push(format!("`{value}`"));
304 } else {
305 fields.push(format!("{value}"));
306 }
307 }
308 _ => {
309 fields.push(format!("{value}"));
310 }
311 }
312 }
313 let fields = {
314 if fields.is_empty() {
315 "*".into()
316 } else {
317 fields.join(",")
318 }
319 };
320 match self.mode.as_str() {
321 "mysql" => {
322 fields.to_string()
323 }
324 "sqlite" => {
325 fields.to_string()
326 }
327 "mssql" => {
328 fields.to_string()
329 }
330 _ => fields.to_string()
331 }
332 }
333 pub fn top(&mut self) -> String {
334 match self.mode.as_str() {
335 "mssql" => {
336 let wheres = self.where_sql();
337 if !self.top2.is_empty() {
338 let order = self.order();
339 if order.is_empty() {
340 self.top = format!("(select ROW_NUMBER() OVER(ORDER BY rand()) as ROW,* from {} {}) as ", self.table, wheres);
341 } else {
342 self.top = format!("(select ROW_NUMBER() OVER({}) as ROW,* from {} {}) as ", order, self.table, wheres);
343 }
344 return self.top.to_string();
345 }
346 self.top.to_string()
347 }
348 _ => {
349 "".to_string()
350 }
351 }
352 }
353 pub fn top2(&mut self) -> String {
354 match self.mode.as_str() {
355 "mssql" => {
356 if self.where_and.is_empty() && self.where_or.is_empty() && !self.top2.is_empty() {
357 return format!("where {}", self.top2);
358 }
359 if (!self.where_and.is_empty() || !self.where_or.is_empty()) && !self.top2.is_empty() {
360 return format!("AND {}", self.top2);
361 }
362 self.top2.to_string()
363 }
364 _ => {
365 "".to_string()
366 }
367 }
368 }
369 pub fn table(&mut self) -> String {
370 match self.mode.as_str() {
371 "mssql" => {
372 if !self.top2.is_empty() {
373 return "t".to_string();
374 }
375 self.table.to_string()
376 }
377 _ => {
378 self.table.to_string()
379 }
380 }
381 }
382 pub fn join(&mut self) -> String {
383 match self.mode.as_str() {
384 "mssql" => {
385 self.join.join(" ")
386 }
387 _ => {
388 self.join.join(" ")
389 }
390 }
391 }
392
393 pub fn join_inner(&mut self) -> String {
395 match self.mode.as_str() {
396 "mysql" => {
397 if self.join_inner.is_empty() {
399 "".to_string()
400 } else {
401 self.join_inner.join(" ")
402 }
403 }
404 _ => {
405 "".to_string()
406 }
407 }
408 }
409
410
411 pub fn order(&mut self) -> String {
412 let mut sql = vec![];
413 for (field, item) in self.order.entries() {
414 match self.mode.as_str() {
415 "mssql" => {
416 if DISABLE_FIELD.contains(&field) {
417 sql.push(format!("[{field}] {item}"));
418 } else {
419 sql.push(format!("{field} {item}"));
420 }
421 }
422
423 "pgsql" => {
424 if DISABLE_FIELD.contains(&field) {
425 sql.push(format!("\"{field}\" {item}"));
426 } else {
427 sql.push(format!("{field} {item}"));
428 }
429 }
430 _ => {
431 if DISABLE_FIELD.contains(&field) {
432 sql.push(format!("`{field}` {item}"));
433 } else {
434 sql.push(format!("{field} {item}"));
435 }
436 }
437 }
438 }
439 if !sql.is_empty() {
440 return format!("ORDER BY {}", sql.join(","));
441 }
442 "".to_string()
443 }
444 pub fn group(&mut self) -> String {
445 let mut sql = Vec::with_capacity(self.group.len());
447
448 for (_, field) in self.group.entries() {
449 let field_str = field.as_str().unwrap_or("");
450 if DISABLE_FIELD.contains(&field_str) {
451 sql.push(format!("`{}`", field_str));
452 } else if field_str.contains(".") {
453 sql.push(field_str.to_string());
454 } else {
455 sql.push(format!("{}.{}", self.table, field_str));
456 }
457 }
458 if !sql.is_empty() {
459 format!("GROUP BY {}", sql.join(","))
460 } else {
461 "".to_string()
462 }
463 }
464 pub fn distinct(&self) -> String {
465 if self.distinct {
466 "DISTINCT".to_string()
467 } else {
468 "".to_string()
469 }
470 }
471 pub fn select_sql(&mut self) -> String {
472 format!("SELECT {} {} FROM {} {} {} {} {} {} {} {} {}", self.distinct(), self.fields(), self.top(), self.table(), self.join(), self.join_inner(), self.where_sql(), self.top2(), self.group(), self.order(), self.page_limit_sql())
473 }
474}