chain_builder/
sqlx_bind.rs1use crate::builder::QueryBuilder;
14use crate::dialect::Dialect;
15use crate::value::Value;
16
17#[cfg(feature = "sqlx_mysql")]
18use crate::dialect::MySql;
19#[cfg(feature = "sqlx_postgres")]
20use crate::dialect::Postgres;
21#[cfg(feature = "sqlx_sqlite")]
22use crate::dialect::Sqlite;
23
24pub trait SqlxDialect: Dialect + private::Sealed {
29 type Database: sqlx::Database<Arguments: sqlx::IntoArguments<Self::Database>>;
35
36 fn bind_arguments(binds: &[Value]) -> <Self::Database as sqlx::Database>::Arguments;
42}
43
44mod private {
45 pub trait Sealed {}
47
48 #[cfg(feature = "sqlx_postgres")]
49 impl Sealed for crate::dialect::Postgres {}
50 #[cfg(feature = "sqlx_mysql")]
51 impl Sealed for crate::dialect::MySql {}
52 #[cfg(feature = "sqlx_sqlite")]
53 impl Sealed for crate::dialect::Sqlite {}
54}
55
56#[cfg(feature = "sqlx_postgres")]
57impl SqlxDialect for Postgres {
58 type Database = sqlx::Postgres;
59
60 fn bind_arguments(binds: &[Value]) -> sqlx::postgres::PgArguments {
61 use sqlx::Arguments;
62 let mut arguments = sqlx::postgres::PgArguments::default();
63 for bind in binds {
64 match bind {
66 Value::Null => {
67 let _ = arguments.add(Option::<String>::None);
68 }
69 Value::Bool(b) => {
70 let _ = arguments.add(*b);
71 }
72 Value::I64(i) => {
73 let _ = arguments.add(*i);
74 }
75 Value::F64(f) => {
76 let _ = arguments.add(*f);
77 }
78 Value::Text(s) => {
79 let _ = arguments.add(s.clone());
80 }
81 Value::Bytes(b) => {
82 let _ = arguments.add(b.clone());
83 }
84 #[cfg(feature = "json")]
85 Value::Json(j) => {
86 let _ = arguments.add(serde_json::to_string(j).unwrap_or_default());
88 }
89 #[cfg(feature = "uuid")]
90 Value::Uuid(u) => {
91 let _ = arguments.add(*u);
92 }
93 #[cfg(feature = "chrono")]
94 Value::DateTimeUtc(dt) => {
95 let _ = arguments.add(*dt);
96 }
97 #[cfg(feature = "chrono")]
98 Value::NaiveDateTime(dt) => {
99 let _ = arguments.add(*dt);
100 }
101 #[cfg(feature = "chrono")]
102 Value::NaiveDate(d) => {
103 let _ = arguments.add(*d);
104 }
105 #[cfg(feature = "chrono")]
106 Value::NaiveTime(t) => {
107 let _ = arguments.add(*t);
108 }
109 }
110 }
111 arguments
112 }
113}
114
115#[cfg(feature = "sqlx_mysql")]
116impl SqlxDialect for MySql {
117 type Database = sqlx::MySql;
118
119 fn bind_arguments(binds: &[Value]) -> sqlx::mysql::MySqlArguments {
120 use sqlx::Arguments;
121 let mut arguments = sqlx::mysql::MySqlArguments::default();
122 for bind in binds {
123 match bind {
125 Value::Null => {
126 let _ = arguments.add(Option::<String>::None);
127 }
128 Value::Bool(b) => {
129 let _ = arguments.add(*b);
130 }
131 Value::I64(i) => {
132 let _ = arguments.add(*i);
133 }
134 Value::F64(f) => {
135 let _ = arguments.add(*f);
136 }
137 Value::Text(s) => {
138 let _ = arguments.add(s.clone());
139 }
140 Value::Bytes(b) => {
141 let _ = arguments.add(b.clone());
142 }
143 #[cfg(feature = "json")]
144 Value::Json(j) => {
145 let _ = arguments.add(serde_json::to_string(j).unwrap_or_default());
147 }
148 #[cfg(feature = "uuid")]
149 Value::Uuid(u) => {
150 let _ = arguments.add(*u);
151 }
152 #[cfg(feature = "chrono")]
153 Value::DateTimeUtc(dt) => {
154 let _ = arguments.add(*dt);
155 }
156 #[cfg(feature = "chrono")]
157 Value::NaiveDateTime(dt) => {
158 let _ = arguments.add(*dt);
159 }
160 #[cfg(feature = "chrono")]
161 Value::NaiveDate(d) => {
162 let _ = arguments.add(*d);
163 }
164 #[cfg(feature = "chrono")]
165 Value::NaiveTime(t) => {
166 let _ = arguments.add(*t);
167 }
168 }
169 }
170 arguments
171 }
172}
173
174#[cfg(feature = "sqlx_sqlite")]
175impl SqlxDialect for Sqlite {
176 type Database = sqlx::Sqlite;
177
178 fn bind_arguments(binds: &[Value]) -> sqlx::sqlite::SqliteArguments {
179 use sqlx::Arguments;
180 let mut arguments = sqlx::sqlite::SqliteArguments::default();
183 for bind in binds {
184 match bind {
186 Value::Null => {
187 let _ = arguments.add(Option::<String>::None);
188 }
189 Value::Bool(b) => {
190 let _ = arguments.add(*b);
191 }
192 Value::I64(i) => {
193 let _ = arguments.add(*i);
194 }
195 Value::F64(f) => {
196 let _ = arguments.add(*f);
197 }
198 Value::Text(s) => {
199 let _ = arguments.add(s.clone());
200 }
201 Value::Bytes(b) => {
202 let _ = arguments.add(b.clone());
203 }
204 #[cfg(feature = "json")]
205 Value::Json(j) => {
206 let _ = arguments.add(serde_json::to_string(j).unwrap_or_default());
208 }
209 #[cfg(feature = "uuid")]
210 Value::Uuid(u) => {
211 let _ = arguments.add(*u);
212 }
213 #[cfg(feature = "chrono")]
214 Value::DateTimeUtc(dt) => {
215 let _ = arguments.add(*dt);
216 }
217 #[cfg(feature = "chrono")]
218 Value::NaiveDateTime(dt) => {
219 let _ = arguments.add(*dt);
220 }
221 #[cfg(feature = "chrono")]
222 Value::NaiveDate(d) => {
223 let _ = arguments.add(*d);
224 }
225 #[cfg(feature = "chrono")]
226 Value::NaiveTime(t) => {
227 let _ = arguments.add(*t);
228 }
229 }
230 }
231 arguments
232 }
233}
234
235#[cfg(any(
236 feature = "sqlx_postgres",
237 feature = "sqlx_mysql",
238 feature = "sqlx_sqlite"
239))]
240impl<D: SqlxDialect> QueryBuilder<D> {
241 pub fn to_sqlx_query(
247 &self,
248 ) -> sqlx::query::Query<'_, D::Database, <D::Database as sqlx::Database>::Arguments> {
249 let (sql, binds) = self.to_sql();
250 sqlx::query_with(sqlx::AssertSqlSafe(sql), D::bind_arguments(&binds))
251 }
252
253 pub fn to_sqlx_query_as<T>(
255 &self,
256 ) -> sqlx::query::QueryAs<'_, D::Database, T, <D::Database as sqlx::Database>::Arguments>
257 where
258 T: for<'r> sqlx::FromRow<'r, <D::Database as sqlx::Database>::Row>,
259 {
260 let (sql, binds) = self.to_sql();
261 sqlx::query_as_with(sqlx::AssertSqlSafe(sql), D::bind_arguments(&binds))
262 }
263}