1use super::TableName;
2use super::{DbType, ModelTableField, ModelTableName, TableFields, WhereOption};
3use sqlx::{database::HasArguments, Database, Error, FromRow};
4use sqlx::{Arguments, Executor, IntoArguments};
5use std::vec;
6
7macro_rules! fetch_by_where {
8 ($self_var:ident,$bind_type:ty,$name:ident,$sql:literal,$where_sql:literal,$query_type:ident,$fetch_type:ident,$out_type:ty)=>{
9 impl Select<$bind_type>
10 {
11 pub async fn $name<'c,M,E>(
13 &$self_var,
14 where_sql:&WhereOption,
15 executor:E
16 )
17 ->Result<$out_type,Error>
18 where
19 for<'r> M: FromRow<'r, <$bind_type as Database>::Row>+Send+Unpin+ModelTableField<$bind_type>,
20 for<'n> <$bind_type as HasArguments<'n>>::Arguments:
21 Arguments<'n>+IntoArguments<'n,$bind_type>,
22 E: Executor<'c, Database = $bind_type>
23 {
24 let sql=match where_sql {
25 WhereOption::NoWhere(other)=>{
26 format!(
27 "{} {}",
28 format!(
29 $sql,
30 $self_var.table_field.to_vec().join(","),
31 $self_var.table_name.full_name(),
32 ),
33 other
34 )
35 }
36
37 WhereOption::Where(wsql)=>{
38 format!(
39 $where_sql,
40 $self_var.table_field.to_vec().join(","),
41 $self_var.table_name.full_name(),
42 wsql
43 )
44 }
45 WhereOption::None=>{
46 format!(
47 $sql,
48 $self_var.table_field.to_vec().join(","),
49 $self_var.table_name.full_name()
50 )
51 }
52 };
53 let res=sqlx::$query_type::<$bind_type, M>(sql.as_str());
54 res.$fetch_type(executor).await
55 }
56 }
57 };
58 ($bind_type:ty,$name:ident,$sql:literal,$where_sql:literal,$query_type:ident,$fetch_type:ident,$out_type:ty)=>{
59 fetch_by_where!(self,$bind_type,$name,$sql,$where_sql,$query_type,$fetch_type,$out_type);
60 };
61}
62
63macro_rules! fetch_by_where_scalar {
64 ($self_var:ident,$bind_type:ty,$name:ident,$sql:literal,$where_sql:literal,$fetch_type:ident,$out_type:ty)=>{
65 impl Select<$bind_type>
66 {
67 pub async fn $name<'c,M,E>(
69 &$self_var,
70 field_name:&str,
71 where_sql:&WhereOption,
72 executor:E
73 )
74 -> Result<$out_type, Error>
75 where
76 (M,): for<'r> FromRow<'r, <$bind_type as Database>::Row> + Send + Unpin,
77 M:Send + Unpin,
78 for<'n> <$bind_type as HasArguments<'n>>::Arguments:
79 Arguments<'n>+IntoArguments<'n,$bind_type>,
80 E: Executor<'c, Database = $bind_type>
81 {
82
83
84 let sql=match where_sql {
85 WhereOption::NoWhere(other)=>{
86 format!(
87 "{} {}",
88 format!(
89 $sql,
90 field_name,
91 $self_var.table_name.full_name()
92 ),
93 other
94 )
95 }
96
97 WhereOption::Where(wsql)=>{
98 format!(
99 $where_sql,
100 field_name,
101 $self_var.table_name.full_name(),
102 wsql
103 )
104 }
105 WhereOption::None=>{
106 format!(
107 $sql,
108 field_name,
109 $self_var.table_name.full_name()
110 )
111 }
112 };
113 let res = sqlx::query_scalar::<$bind_type, M,>(sql.as_str());
114 res.$fetch_type(executor).await
115 }
116 }
117 };
118 ($bind_type:ty,$name:ident,$sql:literal,$where_sql:literal,$fetch_type:ident,$out_type:ty)=>{
119 fetch_by_where_scalar!(self,$bind_type,$name,$sql,$where_sql,$fetch_type,$out_type);
120 };
121}
122
123pub struct Select<DB>
125where
126 DB: Database,
127{
128 pub table_name: TableName,
129 pub table_field: TableFields,
130 pub table_pk: TableFields,
131 _marker: std::marker::PhantomData<DB>,
132}
133impl<DB> Select<DB>
134where
135 DB: Database,
136{
137 pub fn new(table_name: TableName, table_field: TableFields, table_pk: TableFields) -> Self {
138 Select {
139 table_name,
140 table_field,
141 table_pk,
142 _marker: Default::default(),
143 }
144 }
145 pub fn type_new<T>() -> Self
146 where
147 T: ModelTableField<DB> + ModelTableName,
148 {
149 Select {
150 table_name: T::table_name(),
151 table_field: T::table_column(),
152 table_pk: T::table_pk(),
153 _marker: Default::default(),
154 }
155 }
156 pub async fn fetch_one_by_scalar_pk<'c, M, PT, E>(
162 &self,
163 pk_scalar: PT,
164 executor: E,
165 ) -> Result<M, Error>
166 where
167 for<'q> PT: 'q + Send + sqlx::Encode<'q, DB> + sqlx::Type<DB>,
168 for<'r> M: FromRow<'r, DB::Row> + Send + Unpin + ModelTableField<DB>,
169 for<'n> <DB as HasArguments<'n>>::Arguments: Arguments<'n> + IntoArguments<'n, DB>,
170 E: Executor<'c, Database = DB>,
171 {
172 let where_sql = scalar_pk_where!(DB, self.table_pk, 0);
173 let sql = format!(
174 "SELECT {} FROM {} WHERE {}",
175 self.table_field.to_vec().join(","),
176 self.table_name.full_name(),
177 where_sql
178 );
179 let mut res = sqlx::query_as::<DB, M>(sql.as_str());
180 res = res.bind(pk_scalar);
181 res.fetch_one(executor).await
182 }
183 pub async fn fetch_one_scalar_by_scalar_pk<'c, M, PT, E>(
189 &self,
190 field_name: &str,
191 pk_scalar: PT,
192 executor: E,
193 ) -> Result<M, Error>
194 where
195 for<'q> PT: 'q + Send + sqlx::Encode<'q, DB> + sqlx::Type<DB>,
196 (M,): for<'r> FromRow<'r, DB::Row> + Send + Unpin,
197 M: Send + Unpin,
198 for<'n> <DB as HasArguments<'n>>::Arguments: Arguments<'n> + IntoArguments<'n, DB>,
199 E: Executor<'c, Database = DB>,
200 {
201 let where_sql = scalar_pk_where!(DB, self.table_pk, 0);
202 let sql = format!(
203 "SELECT {} FROM {} WHERE {}",
204 field_name,
205 self.table_name.full_name(),
206 where_sql
207 );
208 let mut res = sqlx::query_scalar::<DB, M>(sql.as_str());
209 res = res.bind(pk_scalar);
210 res.fetch_one(executor).await
211 }
212 pub async fn reload<'c, M, E>(&self, val: &M, executor: E) -> Result<M, Error>
216 where
217 M: for<'r> FromRow<'r, DB::Row> + Send + Unpin + ModelTableField<DB>,
218 for<'n> <DB as HasArguments<'n>>::Arguments: Arguments<'n> + IntoArguments<'n, DB>,
219 E: Executor<'c, Database = DB>,
220 {
221 let pkf = M::table_pk();
222 let mut where_sql = vec![];
223 for (pos, val) in pkf.0.iter().enumerate() {
224 let bst = DbType::type_new::<DB>().mark(pos);
225 where_sql.push(format!("{}={}", val.name, bst));
226 }
227 let sql = format!(
228 "SELECT {} FROM {} WHERE {}",
229 self.table_field.to_vec().join(","),
230 self.table_name.full_name(),
231 where_sql.join(" and ")
232 );
233 let mut res = sqlx::query_as::<DB, M>(sql.as_str());
234 for fval in pkf.0.iter() {
235 res = val.query_as_sqlx_bind(fval, res);
236 }
237 res.fetch_one(executor).await
238 }
239}
240
241#[cfg(feature = "sqlx-mysql")]
242fetch_by_where!(
243 sqlx::MySql,
244 fetch_all_by_where,
245 "SELECT {} FROM {} ",
246 "SELECT {} FROM {} WHERE {} ",
247 query_as,
248 fetch_all,
249 Vec<M>
250);
251#[cfg(feature = "sqlx-mysql")]
252fetch_by_where!(
253 sqlx::MySql,
254 fetch_one_by_where,
255 "SELECT {} FROM {} LIMIT 1",
256 "SELECT {} FROM {} WHERE {} LIMIT 1",
257 query_as,
258 fetch_one,
259 M
260);
261#[cfg(feature = "sqlx-sqlite")]
262fetch_by_where!(
263 sqlx::Sqlite,
264 fetch_all_by_where,
265 "SELECT {} FROM {} ",
266 "SELECT {} FROM {} WHERE {} ",
267 query_as,
268 fetch_all,
269 Vec<M>
270);
271#[cfg(feature = "sqlx-sqlite")]
272fetch_by_where!(
273 sqlx::Sqlite,
274 fetch_one_by_where,
275 "SELECT {} FROM {} LIMIT 1",
276 "SELECT {} FROM {} WHERE {} LIMIT 1",
277 query_as,
278 fetch_one,
279 M
280);
281#[cfg(feature = "sqlx-postgres")]
282fetch_by_where!(
283 sqlx::Postgres,
284 fetch_all_by_where,
285 "SELECT {} FROM {} ",
286 "SELECT {} FROM {} WHERE {} ",
287 query_as,
288 fetch_all,
289 Vec<M>
290);
291#[cfg(feature = "sqlx-postgres")]
292fetch_by_where!(
293 sqlx::Postgres,
294 fetch_one_by_where,
295 "SELECT {} FROM {} LIMIT 1",
296 "SELECT {} FROM {} WHERE {} LIMIT 1",
297 query_as,
298 fetch_one,
299 M
300);
301#[cfg(feature = "sqlx-mssql")]
302fetch_by_where!(
303 sqlx::Mssql,
304 fetch_all_by_where,
305 "SELECT {} FROM {} ",
306 "SELECT {} FROM {} WHERE {} ",
307 query_as,
308 fetch_all,
309 Vec<M>
310);
311#[cfg(feature = "sqlx-mssql")]
312fetch_by_where!(
313 sqlx::Mssql,
314 fetch_one_by_where,
315 "SELECT TOP 1 {} FROM {}",
316 "SELECT TOP 1 {} FROM {} WHERE {}",
317 query_as,
318 fetch_one,
319 M
320);
321
322#[cfg(feature = "sqlx-mysql")]
323fetch_by_where_scalar!(
324 sqlx::MySql,
325 fetch_all_scalar_by_where,
326 "SELECT {} FROM {} ",
327 "SELECT {} FROM {} WHERE {} ",
328 fetch_all,
329 Vec<M>
330);
331#[cfg(feature = "sqlx-mysql")]
332fetch_by_where_scalar!(
333 sqlx::MySql,
334 fetch_one_scalar_by_where,
335 "SELECT {} FROM {} LIMIT 1",
336 "SELECT {} FROM {} WHERE {} LIMIT 1",
337 fetch_one,
338 M
339);
340#[cfg(feature = "sqlx-sqlite")]
341fetch_by_where_scalar!(
342 sqlx::Sqlite,
343 fetch_all_scalar_by_where,
344 "SELECT {} FROM {} ",
345 "SELECT {} FROM {} WHERE {} ",
346 fetch_all,
347 Vec<M>
348);
349#[cfg(feature = "sqlx-sqlite")]
350fetch_by_where_scalar!(
351 sqlx::Sqlite,
352 fetch_one_scalar_by_where,
353 "SELECT {} FROM {} LIMIT 1",
354 "SELECT {} FROM {} WHERE {} LIMIT 1",
355 fetch_one,
356 M
357);
358#[cfg(feature = "sqlx-postgres")]
359fetch_by_where_scalar!(
360 sqlx::Postgres,
361 fetch_all_scalar_by_where,
362 "SELECT {} FROM {} ",
363 "SELECT {} FROM {} WHERE {} ",
364 fetch_all,
365 Vec<M>
366);
367#[cfg(feature = "sqlx-postgres")]
368fetch_by_where_scalar!(
369 sqlx::Postgres,
370 fetch_one_scalar_by_where,
371 "SELECT {} FROM {} LIMIT 1",
372 "SELECT {} FROM {} WHERE {} LIMIT 1",
373 fetch_one,
374 M
375);
376#[cfg(feature = "sqlx-mssql")]
377fetch_by_where_scalar!(
378 sqlx::Mssql,
379 fetch_all_scalar_by_where,
380 "SELECT {} FROM {} ",
381 "SELECT {} FROM {} WHERE {} ",
382 fetch_all,
383 Vec<M>
384);
385#[cfg(feature = "sqlx-mssql")]
386fetch_by_where_scalar!(
387 sqlx::Mssql,
388 fetch_one_scalar_by_where,
389 "SELECT TOP 1 {} FROM {}",
390 "SELECT TOP 1 {} FROM {} WHERE {}",
391 fetch_one,
392 M
393);