1use crate::config::DatabaseBackend;
4use prax_query::filter::FilterValue;
5
6pub fn placeholder(backend: DatabaseBackend, index: usize) -> String {
8 match backend {
9 DatabaseBackend::Postgres => format!("${}", index),
10 DatabaseBackend::MySql | DatabaseBackend::Sqlite => "?".to_string(),
11 }
12}
13
14pub fn filter_value_to_string(value: &FilterValue) -> String {
16 match value {
17 FilterValue::String(s) => s.clone(),
18 FilterValue::Int(i) => i.to_string(),
19 FilterValue::Float(f) => f.to_string(),
20 FilterValue::Bool(b) => b.to_string(),
21 FilterValue::Null => "NULL".to_string(),
22 FilterValue::Json(j) => j.to_string(),
23 FilterValue::List(arr) => {
24 let items: Vec<String> = arr.iter().map(filter_value_to_string).collect();
25 format!("[{}]", items.join(", "))
26 }
27 }
28}
29
30pub fn placeholders(backend: DatabaseBackend, count: usize, start: usize) -> String {
32 (start..start + count)
33 .map(|i| placeholder(backend, i))
34 .collect::<Vec<_>>()
35 .join(", ")
36}
37
38pub fn quote_identifier(backend: DatabaseBackend, name: &str) -> String {
40 match backend {
41 DatabaseBackend::Postgres => format!("\"{}\"", name.replace('"', "\"\"")),
42 DatabaseBackend::MySql => format!("`{}`", name.replace('`', "``")),
43 DatabaseBackend::Sqlite => format!("\"{}\"", name.replace('"', "\"\"")),
44 }
45}
46
47pub fn rust_to_sql_type(backend: DatabaseBackend, rust_type: &str) -> &'static str {
49 match backend {
50 DatabaseBackend::Postgres => match rust_type {
51 "i32" => "INTEGER",
52 "i64" => "BIGINT",
53 "f32" => "REAL",
54 "f64" => "DOUBLE PRECISION",
55 "bool" => "BOOLEAN",
56 "String" | "&str" => "TEXT",
57 "Vec<u8>" | "&[u8]" => "BYTEA",
58 "Uuid" => "UUID",
59 "DateTime" | "chrono::DateTime" => "TIMESTAMPTZ",
60 "NaiveDate" => "DATE",
61 "NaiveTime" => "TIME",
62 "Decimal" => "DECIMAL",
63 "Json" | "serde_json::Value" => "JSONB",
64 _ => "TEXT",
65 },
66 DatabaseBackend::MySql => match rust_type {
67 "i32" => "INT",
68 "i64" => "BIGINT",
69 "f32" => "FLOAT",
70 "f64" => "DOUBLE",
71 "bool" => "BOOLEAN",
72 "String" | "&str" => "TEXT",
73 "Vec<u8>" | "&[u8]" => "BLOB",
74 "Uuid" => "CHAR(36)",
75 "DateTime" | "chrono::DateTime" => "DATETIME",
76 "NaiveDate" => "DATE",
77 "NaiveTime" => "TIME",
78 "Decimal" => "DECIMAL",
79 "Json" | "serde_json::Value" => "JSON",
80 _ => "TEXT",
81 },
82 DatabaseBackend::Sqlite => match rust_type {
83 "i32" | "i64" => "INTEGER",
84 "f32" | "f64" => "REAL",
85 "bool" => "INTEGER", "String" | "&str" => "TEXT",
87 "Vec<u8>" | "&[u8]" => "BLOB",
88 "Uuid" => "TEXT",
89 "DateTime" | "chrono::DateTime" => "TEXT", "NaiveDate" => "TEXT",
91 "NaiveTime" => "TEXT",
92 "Decimal" => "TEXT",
93 "Json" | "serde_json::Value" => "TEXT", _ => "TEXT",
95 },
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn test_placeholder() {
105 assert_eq!(placeholder(DatabaseBackend::Postgres, 1), "$1");
106 assert_eq!(placeholder(DatabaseBackend::Postgres, 5), "$5");
107 assert_eq!(placeholder(DatabaseBackend::MySql, 1), "?");
108 assert_eq!(placeholder(DatabaseBackend::Sqlite, 1), "?");
109 }
110
111 #[test]
112 fn test_placeholders() {
113 assert_eq!(placeholders(DatabaseBackend::Postgres, 3, 1), "$1, $2, $3");
114 assert_eq!(placeholders(DatabaseBackend::MySql, 3, 1), "?, ?, ?");
115 }
116
117 #[test]
118 fn test_quote_identifier() {
119 assert_eq!(
120 quote_identifier(DatabaseBackend::Postgres, "users"),
121 "\"users\""
122 );
123 assert_eq!(quote_identifier(DatabaseBackend::MySql, "users"), "`users`");
124 assert_eq!(
125 quote_identifier(DatabaseBackend::Sqlite, "users"),
126 "\"users\""
127 );
128
129 assert_eq!(
131 quote_identifier(DatabaseBackend::Postgres, "user\"name"),
132 "\"user\"\"name\""
133 );
134 }
135
136 #[test]
137 fn test_rust_to_sql_type() {
138 assert_eq!(
139 rust_to_sql_type(DatabaseBackend::Postgres, "i32"),
140 "INTEGER"
141 );
142 assert_eq!(rust_to_sql_type(DatabaseBackend::MySql, "i32"), "INT");
143 assert_eq!(rust_to_sql_type(DatabaseBackend::Sqlite, "i32"), "INTEGER");
144
145 assert_eq!(
146 rust_to_sql_type(DatabaseBackend::Postgres, "bool"),
147 "BOOLEAN"
148 );
149 assert_eq!(rust_to_sql_type(DatabaseBackend::Sqlite, "bool"), "INTEGER");
150 }
151}