taitan_orm_parser/field_mapper/base/
keywords_escaper.rs

1use std::borrow::Cow;
2
3pub const MYSQL_KEYWORDS: &[&str] = &[
4    "ACCESSIBLE",
5    "ADD",
6    "ALL",
7    "ALTER",
8    "ANALYZE",
9    "AND",
10    "AS",
11    "ASC",
12    "ASENSITIVE",
13    "BEFORE",
14    "BETWEEN",
15    "BIGINT",
16    "BINARY",
17    "BLOB",
18    "BOTH",
19    "BY",
20    "CALL",
21    "CASCADE",
22    "CASE",
23    "CHANGE",
24    "CHAR",
25    "CHARACTER",
26    "CHECK",
27    "COLLATE",
28    "COLUMN",
29    "CONDITION",
30    "CONSTRAINT",
31    "CONTINUE",
32    "CONVERT",
33    "CREATE",
34    "CROSS",
35    "CURRENT_DATE",
36    "CURRENT_TIME",
37    "CURRENT_TIMESTAMP",
38    "CURRENT_USER",
39    "CURSOR",
40    "DATABASE",
41    "DATABASES",
42    "DAY_HOUR",
43    "DAY_MICROSECOND",
44    "DAY_MINUTE",
45    "DAY_SECOND",
46    "DEC",
47    "DECIMAL",
48    "DECLARE",
49    "DEFAULT",
50    "DELAYED",
51    "DELETE",
52    "DESC",
53    "DESCRIBE",
54    "DETERMINISTIC",
55    "DISTINCT",
56    "DISTINCTROW",
57    "DIV",
58    "DOUBLE",
59    "DROP",
60    "DUAL",
61    "EACH",
62    "ELSE",
63    "ELSEIF",
64    "ENCLOSED",
65    "ESCAPED",
66    "EXISTS",
67    "EXIT",
68    "EXPLAIN",
69    "FALSE",
70    "FETCH",
71    "FLOAT",
72    "FLOAT4",
73    "FLOAT8",
74    "FOR",
75    "FORCE",
76    "FOREIGN",
77    "FROM",
78    "FULLTEXT",
79    "GENERATED",
80    "GET",
81    "GRANT",
82    "GROUP",
83    "HAVING",
84    "HIGH_PRIORITY",
85    "HOUR_MICROSECOND",
86    "HOUR_MINUTE",
87    "HOUR_SECOND",
88    "IF",
89    "IGNORE",
90    "IN",
91    "INDEX",
92    "INFILE",
93    "INNER",
94    "INOUT",
95    "INSENSITIVE",
96    "INSERT",
97    "INT",
98    "INT1",
99    "INT2",
100    "INT3",
101    "INT4",
102    "INT8",
103    "INTEGER",
104    "INTERVAL",
105    "INTO",
106    "IO_AFTER_GTIDS",
107    "IO_BEFORE_GTIDS",
108    "IS",
109    "ITERATE",
110    "JOIN",
111    "KEY",
112    "KEYS",
113    "KILL",
114    "LEADING",
115    "LEAVE",
116    "LEFT",
117    "LIKE",
118    "LIMIT",
119    "LINEAR",
120    "LINES",
121    "LOAD",
122    "LOCALTIME",
123    "LOCALTIMESTAMP",
124    "LOCK",
125    "LONG",
126    "LONGBLOB",
127    "LONGTEXT",
128    "LOOP",
129    "LOW_PRIORITY",
130    "MASTER_BIND",
131    "MASTER_SSL_VERIFY_SERVER_CERT",
132    "MATCH",
133    "MAXVALUE",
134    "MEDIUMBLOB",
135    "MEDIUMINT",
136    "MEDIUMTEXT",
137    "MIDDLEINT",
138    "MINUTE_MICROSECOND",
139    "MINUTE_SECOND",
140    "MOD",
141    "MODIFIES",
142    "NATURAL",
143    "NOT",
144    "NO_WRITE_TO_BINLOG",
145    "NULL",
146    "NUMERIC",
147    "ON",
148    "OPTIMIZE",
149    "OPTION",
150    "OPTIONALLY",
151    "OR",
152    "ORDER",
153    "OUT",
154    "OUTER",
155    "OUTFILE",
156    "PARTITION",
157    "PRECISION",
158    "PRIMARY",
159    "PROCEDURE",
160    "PURGE",
161    "RANGE",
162    "READ",
163    "READS",
164    "READ_WRITE",
165    "REAL",
166    "REFERENCES",
167    "REGEXP",
168    "RELEASE",
169    "RENAME",
170    "REPEAT",
171    "REPLACE",
172    "REQUIRE",
173    "RESIGNAL",
174    "RESTRICT",
175    "RETURN",
176    "REVOKE",
177    "RIGHT",
178    "RLIKE",
179    "SCHEMA",
180    "SCHEMAS",
181    "SECOND_MICROSECOND",
182    "SELECT",
183    "SENSITIVE",
184    "SEPARATOR",
185    "SET",
186    "SHOW",
187    "SIGNAL",
188    "SMALLINT",
189    "SPATIAL",
190    "SPECIFIC",
191    "SQL",
192    "SQLEXCEPTION",
193    "SQLSTATE",
194    "SQLWARNING",
195    "SQL_BIG_RESULT",
196    "SQL_CALC_FOUND_ROWS",
197    "SQL_SMALL_RESULT",
198    "SSL",
199    "STARTING",
200    "STORED",
201    "STRAIGHT_JOIN",
202    "TABLE",
203    "TERMINATED",
204    "THEN",
205    "TINYBLOB",
206    "TINYINT",
207    "TINYTEXT",
208    "TO",
209    "TRAILING",
210    "TRIGGER",
211    "TRUE",
212    "UNDO",
213    "UNION",
214    "UNIQUE",
215    "UNLOCK",
216    "UNSIGNED",
217    "UPDATE",
218    "USAGE",
219    "USE",
220    "USING",
221    "UTC_DATE",
222    "UTC_TIME",
223    "UTC_TIMESTAMP",
224    "VALUES",
225    "VARBINARY",
226    "VARCHAR",
227    "VARCHARACTER",
228    "VARYING",
229    "VIRTUAL",
230    "WHEN",
231    "WHERE",
232    "WHILE",
233    "WITH",
234    "WRITE",
235    "XOR",
236    "YEAR_MONTH",
237    "ZEROFILL",
238];
239
240pub const POSTGRES_KEYWORDS: &[&str] = &[
241    "ALL",
242    "ANALYSE",
243    "ANALYZE",
244    "AND",
245    "ANY",
246    "ARRAY",
247    "AS",
248    "ASC",
249    "ASYMMETRIC",
250    "AUTHORIZATION",
251    "BINARY",
252    "BOTH",
253    "CASE",
254    "CAST",
255    "CHECK",
256    "COLLATE",
257    "COLLATION",
258    "COLUMN",
259    "CONCURRENTLY",
260    "CONSTRAINT",
261    "CREATE",
262    "CROSS",
263    "CURRENT_CATALOG",
264    "CURRENT_DATE",
265    "CURRENT_ROLE",
266    "CURRENT_SCHEMA",
267    "CURRENT_TIME",
268    "CURRENT_TIMESTAMP",
269    "CURRENT_USER",
270    "DEFAULT",
271    "DEFERRABLE",
272    "DEFERRED",
273    "DELETE",
274    "DESC",
275    "DISTINCT",
276    "DO",
277    "ELSE",
278    "END",
279    "EXCEPT",
280    "FALSE",
281    "FETCH",
282    "FOR",
283    "FOREIGN",
284    "FREEZE",
285    "FROM",
286    "FULL",
287    "GRANT",
288    "GROUP",
289    "HAVING",
290    "ILIKE",
291    "IN",
292    "INITIALLY",
293    "INNER",
294    "INSERT",
295    "INTERSECT",
296    "INTO",
297    "IS",
298    "ISNULL",
299    "JOIN",
300    "LATERAL",
301    "LEADING",
302    "LEFT",
303    "LIKE",
304    "LIMIT",
305    "LOCALTIME",
306    "LOCALTIMESTAMP",
307    "NATURAL",
308    "NOT",
309    "NOTNULL",
310    "NULL",
311    "OFFSET",
312    "ON",
313    "ONLY",
314    "OR",
315    "ORDER",
316    "OUTER",
317    "OVERLAPS",
318    "PLACING",
319    "PRIMARY",
320    "REFERENCES",
321    "RETURNING",
322    "RIGHT",
323    "SELECT",
324    "SESSION_USER",
325    "SIMILAR",
326    "SOME",
327    "SYMMETRIC",
328    "TABLE",
329    "TABLESAMPLE",
330    "THEN",
331    "TO",
332    "TRAILING",
333    "TRUE",
334    "UNION",
335    "UNIQUE",
336    "UPDATE",
337    "USER",
338    "USING",
339    "VARIADIC",
340    "VERBOSE",
341    "WHEN",
342    "WHERE",
343    "WINDOW",
344    "WITH",
345];
346
347pub const SQLITE_KEYWORDS: &[&str] = &[
348    "ABORT",
349    "ACTION",
350    "ADD",
351    "AFTER",
352    "ALL",
353    "ALTER",
354    "ANALYZE",
355    "AND",
356    "AS",
357    "ASC",
358    "ATTACH",
359    "AUTOINCREMENT",
360    "BEFORE",
361    "BEGIN",
362    "BETWEEN",
363    "BY",
364    "CASCADE",
365    "CASE",
366    "CAST",
367    "CHECK",
368    "COLLATE",
369    "COLUMN",
370    "COMMIT",
371    "CONFLICT",
372    "CONSTRAINT",
373    "CREATE",
374    "CROSS",
375    "CURRENT_DATE",
376    "CURRENT_TIME",
377    "CURRENT_TIMESTAMP",
378    "DATABASE",
379    "DEFAULT",
380    "DEFERRABLE",
381    "DEFERRED",
382    "DELETE",
383    "DESC",
384    "DETACH",
385    "DISTINCT",
386    "DROP",
387    "EACH",
388    "ELSE",
389    "END",
390    "ESCAPE",
391    "EXCEPT",
392    "EXCLUSIVE",
393    "EXISTS",
394    "EXPLAIN",
395    "FAIL",
396    "FOR",
397    "FOREIGN",
398    "FROM",
399    "FULL",
400    "GLOB",
401    "GROUP",
402    "HAVING",
403    "IF",
404    "IGNORE",
405    "IMMEDIATE",
406    "IN",
407    "INDEX",
408    "INDEXED",
409    "INITIALLY",
410    "INNER",
411    "INSERT",
412    "INSTEAD",
413    "INTERSECT",
414    "INTO",
415    "IS",
416    "ISNULL",
417    "JOIN",
418    "KEY",
419    "LEFT",
420    "LIKE",
421    "LIMIT",
422    "MATCH",
423    "NATURAL",
424    "NO",
425    "NOT",
426    "NOTNULL",
427    "NULL",
428    "OF",
429    "OFFSET",
430    "ON",
431    "OR",
432    "ORDER",
433    "OUTER",
434    "PLAN",
435    "PRAGMA",
436    "PRIMARY",
437    "QUERY",
438    "RAISE",
439    "RECURSIVE",
440    "REFERENCES",
441    "REGEXP",
442    "REINDEX",
443    "RELEASE",
444    "RENAME",
445    "REPLACE",
446    "RESTRICT",
447    "RIGHT",
448    "ROLLBACK",
449    "ROW",
450    "SAVEPOINT",
451    "SELECT",
452    "SET",
453    "TABLE",
454    "TEMP",
455    "TEMPORARY",
456    "THEN",
457    "TO",
458    "TRANSACTION",
459    "TRIGGER",
460    "UNION",
461    "UNIQUE",
462    "UPDATE",
463    "USING",
464    "VACUUM",
465    "VALUES",
466    "VIEW",
467    "VIRTUAL",
468    "WHEN",
469    "WHERE",
470    "WITH",
471    "WITHOUT",
472];
473
474pub const COMMON_KEYWORDS: &[&str] = &[
475    "ALL",
476    "AND",
477    "AS",
478    "ASC",
479    "BETWEEN",
480    "BY",
481    "CASE",
482    "CHECK",
483    "COLLATE",
484    "COLUMN",
485    "CREATE",
486    "CROSS",
487    "DEFAULT",
488    "DELETE",
489    "DESC",
490    "DISTINCT",
491    "DROP",
492    "ELSE",
493    "END",
494    "EXISTS",
495    "FOREIGN",
496    "FROM",
497    "FULL",
498    "GROUP",
499    "HAVING",
500    "IN",
501    "INDEX",
502    "INNER",
503    "INSERT",
504    "INTO",
505    "IS",
506    "JOIN",
507    "LEFT",
508    "LIKE",
509    "LIMIT",
510    "NOT",
511    "NULL",
512    "ON",
513    "OR",
514    "ORDER",
515    "OUTER",
516    "PRIMARY",
517    "REFERENCES",
518    "SELECT",
519    "SET",
520    "TABLE",
521    "THEN",
522    "TO",
523    "UNION",
524    "UNIQUE",
525    "UPDATE",
526    "USING",
527    "VALUES",
528    "WHEN",
529    "WHERE",
530    "WITH",
531];
532
533fn contains_ignore_case<T: AsRef<str>>(haystack: &[T], needle: &str) -> bool {
534    let needle_lower = needle.to_lowercase();
535    haystack
536        .iter()
537        .any(|item| item.as_ref().to_lowercase() == needle_lower)
538}
539
540pub trait KeywordsEscaper {
541    fn gen_upsert_name(&self, word: &str) -> String;
542    fn is_keyword(&self, word: &str) -> bool;
543    fn escape_word(&self, word: &str) -> String;
544    fn escape<'a>(&self, word: &'a str) -> Cow<'a, str> {
545        let trimmed = word.trim();
546        if self.is_keyword(trimmed) {
547            Cow::Owned(self.escape_word(trimmed))
548        } else {
549            Cow::Borrowed(trimmed)
550        }
551    }
552}
553
554#[derive(Default, Debug, Clone)]
555pub struct MySqlKeywordEscaper;
556impl KeywordsEscaper for MySqlKeywordEscaper {
557    fn gen_upsert_name(&self, word: &str) -> String {
558        format!("VALUES({})", word)
559    }
560
561    fn is_keyword(&self, word: &str) -> bool {
562        contains_ignore_case(MYSQL_KEYWORDS, word)
563    }
564    fn escape_word(&self, word: &str) -> String {
565        format!("`{}`", word)
566    }
567}
568
569#[derive(Default, Debug, Clone)]
570pub struct PostgresKeywordEscaper;
571impl KeywordsEscaper for PostgresKeywordEscaper {
572    fn gen_upsert_name(&self, word: &str) -> String {
573        format!("EXCLUDED.{}", word)
574    }
575    fn is_keyword(&self, word: &str) -> bool {
576        contains_ignore_case(POSTGRES_KEYWORDS, word)
577    }
578    fn escape_word(&self, word: &str) -> String {
579        format!("\"{}\"", word)
580    }
581}
582
583#[derive(Default, Debug, Clone)]
584pub struct SqliteKeywordEscaper;
585impl KeywordsEscaper for SqliteKeywordEscaper {
586    fn gen_upsert_name(&self, word: &str) -> String {
587        format!("EXCLUDED.{}", word)
588    }
589    fn is_keyword(&self, word: &str) -> bool {
590        contains_ignore_case(SQLITE_KEYWORDS, word)
591    }
592    fn escape_word(&self, word: &str) -> String {
593        format!("\"{}\"", word)
594    }
595}