1
use crate::{
2
    crud::{CrudOperations, Transaction},
3
    mapper::RowMapper,
4
};
5
#[cfg(feature = "mysql")]
6
use canyon_connection::mysql_async::{self, prelude::ToValue};
7
#[cfg(feature = "mssql")]
8
use canyon_connection::tiberius::{self, ColumnData, IntoSql};
9
#[cfg(feature = "postgres")]
10
use canyon_connection::tokio_postgres::{self, types::ToSql};
11

            
12
use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, Utc};
13

            
14
use std::{any::Any, borrow::Cow};
15

            
16
/// Created for retrieve the field's name of a field of a struct, giving
17
/// the Canyon's autogenerated enum with the variants that maps this
18
/// fields.
19
///
20
/// ```
21
/// pub struct Struct<'a> {
22
///     pub some_field: &'a str
23
/// }
24
///
25
/// // Autogenerated enum
26
/// #[derive(Debug)]
27
/// #[allow(non_camel_case_types)]
28
/// pub enum StructField {
29
///     some_field
30
/// }
31
/// ```
32
/// So, to retrieve the field's name, something like this w'd be used on some part
33
/// of the Canyon's Manager crate, to wire the necessary code to pass the field
34
/// name, retrieved from the enum variant, to a called.
35
///
36
/// // Something like:
37
/// `let struct_field_name_from_variant = StructField::some_field.field_name_as_str();`
38
pub trait FieldIdentifier<T>
39
where
40
    T: Transaction<T> + CrudOperations<T> + RowMapper<T>,
41
{
42
    fn as_str(&self) -> &'static str;
43
}
44

            
45
/// Represents some kind of introspection to make the implementors
46
/// able to retrieve a value inside some variant of an associated enum type.
47
/// and convert it to a tuple struct formed by the column name as an String,
48
/// and the dynamic value of the [`QueryParameter<'_>`] trait object contained
49
/// inside the variant requested,
50
/// enabling a conversion of that value into something
51
/// that can be part of an SQL query.
52
///
53
///
54
/// Ex:
55
/// `SELECT * FROM some_table WHERE id = 2`
56
///
57
/// That '2' it's extracted from some enum that implements [`FieldValueIdentifier`],
58
/// where usually the variant w'd be something like:
59
///
60
/// ```
61
/// pub enum Enum {
62
///     IntVariant(i32)
63
/// }
64
/// ```
65
pub trait FieldValueIdentifier<'a, T>
66
where
67
    T: Transaction<T> + CrudOperations<T> + RowMapper<T>,
68
{
69
    fn value(self) -> (&'static str, &'a dyn QueryParameter<'a>);
70
}
71

            
72
/// Bounds to some type T in order to make it callable over some fn parameter T
73
///
74
/// Represents the ability of an struct to be considered as candidate to perform
75
/// actions over it as it holds the 'parent' side of a foreign key relation.
76
///
77
/// Usually, it's used on the Canyon macros to retrieve the column that
78
/// this side of the relation it's representing
79
pub trait ForeignKeyable<T> {
80
    /// Retrieves the field related to the column passed in
81
    fn get_fk_column(&self, column: &str) -> Option<&dyn QueryParameter<'_>>;
82
}
83

            
84
/// Generic abstraction to represent any of the Row types
85
/// from the client crates
86
pub trait Row {
87
    fn as_any(&self) -> &dyn Any;
88
}
89

            
90
#[cfg(feature = "postgres")]
91
impl Row for tokio_postgres::Row {
92
    fn as_any(&self) -> &dyn Any {
93
        self
94
    }
95
}
96

            
97
#[cfg(feature = "mssql")]
98
impl Row for tiberius::Row {
99
    fn as_any(&self) -> &dyn Any {
100
        self
101
    }
102
}
103

            
104
#[cfg(feature = "mysql")]
105
impl Row for mysql_async::Row {
106
    fn as_any(&self) -> &dyn Any {
107
        self
108
    }
109
}
110

            
111
/// Generic abstraction for hold a Column type that will be one of the Column
112
/// types present in the dependent crates
113
// #[derive(Copy, Clone)]
114
pub struct Column<'a> {
115
    name: Cow<'a, str>,
116
    type_: ColumnType,
117
}
118
impl<'a> Column<'a> {
119
    pub fn name(&self) -> &str {
120
        &self.name
121
    }
122
    pub fn column_type(&self) -> &ColumnType {
123
        &self.type_
124
    }
125
    // pub fn type_(&'a self) -> &'_ dyn Type {
126
    //     match (*self).type_ {
127
    //         #[cfg(feature = "postgres")] ColumnType::Postgres(v) => v as &'a dyn Type,
128
    //         #[cfg(feature = "mssql")] ColumnType::SqlServer(v) => v as &'a dyn Type,
129
    //     }
130
    // }
131
}
132

            
133
pub trait Type {
134
    fn as_any(&self) -> &dyn Any;
135
}
136
#[cfg(feature = "postgres")]
137
impl Type for tokio_postgres::types::Type {
138
    fn as_any(&self) -> &dyn Any {
139
        self
140
    }
141
}
142
#[cfg(feature = "mssql")]
143
impl Type for tiberius::ColumnType {
144
    fn as_any(&self) -> &dyn Any {
145
        self
146
    }
147
}
148
#[cfg(feature = "mysql")]
149
impl Type for mysql_async::consts::ColumnType {
150
    fn as_any(&self) -> &dyn Any {
151
        self
152
    }
153
}
154

            
155
/// Wrapper over the dependencies Column's types
156
pub enum ColumnType {
157
    #[cfg(feature = "postgres")]
158
    Postgres(tokio_postgres::types::Type),
159
    #[cfg(feature = "mssql")]
160
    SqlServer(tiberius::ColumnType),
161
    #[cfg(feature = "mysql")]
162
    MySQL(mysql_async::consts::ColumnType),
163
}
164

            
165
pub trait RowOperations {
166
    #[cfg(feature = "postgres")]
167
    fn get_postgres<'a, Output>(&'a self, col_name: &'a str) -> Output
168
    where
169
        Output: tokio_postgres::types::FromSql<'a>;
170
    #[cfg(feature = "mssql")]
171
    fn get_mssql<'a, Output>(&'a self, col_name: &'a str) -> Output
172
    where
173
        Output: tiberius::FromSql<'a>;
174
    #[cfg(feature = "mysql")]
175
    fn get_mysql<'a, Output>(&'a self, col_name: &'a str) -> Output
176
    where
177
        Output: mysql_async::prelude::FromValue;
178

            
179
    #[cfg(feature = "postgres")]
180
    fn get_postgres_opt<'a, Output>(&'a self, col_name: &'a str) -> Option<Output>
181
    where
182
        Output: tokio_postgres::types::FromSql<'a>;
183
    #[cfg(feature = "mssql")]
184
    fn get_mssql_opt<'a, Output>(&'a self, col_name: &'a str) -> Option<Output>
185
    where
186
        Output: tiberius::FromSql<'a>;
187

            
188
    #[cfg(feature = "mysql")]
189
    fn get_mysql_opt<'a, Output>(&'a self, col_name: &'a str) -> Option<Output>
190
    where
191
        Output: mysql_async::prelude::FromValue;
192

            
193
    fn columns(&self) -> Vec<Column>;
194
}
195

            
196
impl RowOperations for &dyn Row {
197
    #[cfg(feature = "postgres")]
198
    fn get_postgres<'a, Output>(&'a self, col_name: &'a str) -> Output
199
    where
200
        Output: tokio_postgres::types::FromSql<'a>,
201
    {
202
        if let Some(row) = self.as_any().downcast_ref::<tokio_postgres::Row>() {
203
            return row.get::<&str, Output>(col_name);
204
        };
205
        panic!() // TODO into result and propagate
206
    }
207
    #[cfg(feature = "mssql")]
208
    fn get_mssql<'a, Output>(&'a self, col_name: &'a str) -> Output
209
    where
210
        Output: tiberius::FromSql<'a>,
211
    {
212
        if let Some(row) = self.as_any().downcast_ref::<tiberius::Row>() {
213
            return row
214
                .get::<Output, &str>(col_name)
215
                .expect("Failed to obtain a row in the MSSQL migrations");
216
        };
217
        panic!() // TODO into result and propagate
218
    }
219

            
220
    #[cfg(feature = "mysql")]
221
    fn get_mysql<'a, Output>(&'a self, col_name: &'a str) -> Output
222
    where
223
        Output: mysql_async::prelude::FromValue,
224
    {
225
        self.get_mysql_opt(col_name)
226
            .expect("Failed to obtain a column in the MySql")
227
    }
228

            
229
    #[cfg(feature = "postgres")]
230
    fn get_postgres_opt<'a, Output>(&'a self, col_name: &'a str) -> Option<Output>
231
    where
232
        Output: tokio_postgres::types::FromSql<'a>,
233
    {
234
        if let Some(row) = self.as_any().downcast_ref::<tokio_postgres::Row>() {
235
            return row.get::<&str, Option<Output>>(col_name);
236
        };
237
        panic!() // TODO into result and propagate
238
    }
239

            
240
    #[cfg(feature = "mssql")]
241
    fn get_mssql_opt<'a, Output>(&'a self, col_name: &'a str) -> Option<Output>
242
    where
243
        Output: tiberius::FromSql<'a>,
244
    {
245
        if let Some(row) = self.as_any().downcast_ref::<tiberius::Row>() {
246
            return row.get::<Output, &str>(col_name);
247
        };
248
        panic!() // TODO into result and propagate
249
    }
250
    #[cfg(feature = "mysql")]
251
    fn get_mysql_opt<'a, Output>(&'a self, col_name: &'a str) -> Option<Output>
252
    where
253
        Output: mysql_async::prelude::FromValue,
254
    {
255
        if let Some(row) = self.as_any().downcast_ref::<mysql_async::Row>() {
256
            return row.get::<Output, &str>(col_name);
257
        };
258
        panic!() // TODO into result and propagate
259
    }
260

            
261
    fn columns(&self) -> Vec<Column> {
262
        let mut cols = vec![];
263

            
264
        #[cfg(feature = "postgres")]
265
        {
266
            if self.as_any().is::<tokio_postgres::Row>() {
267
                self.as_any()
268
                    .downcast_ref::<tokio_postgres::Row>()
269
                    .expect("Not a tokio postgres Row for column")
270
                    .columns()
271
                    .iter()
272
                    .for_each(|c| {
273
                        cols.push(Column {
274
                            name: Cow::from(c.name()),
275
                            type_: ColumnType::Postgres(c.type_().to_owned()),
276
                        })
277
                    })
278
            }
279
        }
280
        #[cfg(feature = "mssql")]
281
        {
282
            if self.as_any().is::<tiberius::Row>() {
283
                self.as_any()
284
                    .downcast_ref::<tiberius::Row>()
285
                    .expect("Not a Tiberius Row for column")
286
                    .columns()
287
                    .iter()
288
                    .for_each(|c| {
289
                        cols.push(Column {
290
                            name: Cow::from(c.name()),
291
                            type_: ColumnType::SqlServer(c.column_type()),
292
                        })
293
                    })
294
            };
295
        }
296
        #[cfg(feature = "mysql")]
297
        {
298
            if let Some(mysql_row) = self.as_any().downcast_ref::<mysql_async::Row>() {
299
                mysql_row.columns_ref().iter().for_each(|c| {
300
                    cols.push(Column {
301
                        name: c.name_str(),
302
                        type_: ColumnType::MySQL(c.column_type()),
303
                    })
304
                })
305
            }
306
        }
307

            
308
        cols
309
    }
310
}
311

            
312
/// Defines a trait for represent type bounds against the allowed
313
/// data types supported by Canyon to be used as query parameters.
314
pub trait QueryParameter<'a>: std::fmt::Debug + Sync + Send {
315
    #[cfg(feature = "postgres")]
316
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync);
317
    #[cfg(feature = "mssql")]
318
    fn as_sqlserver_param(&self) -> ColumnData<'_>;
319
    #[cfg(feature = "mysql")]
320
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue;
321
}
322

            
323
/// The implementation of the [`canyon_connection::tiberius`] [`IntoSql`] for the
324
/// query parameters.
325
///
326
/// This implementation is necessary because of the generic amplitude
327
/// of the arguments of the [`Transaction::query`], that should work with
328
/// a collection of [`QueryParameter<'a>`], in order to allow a workflow
329
/// that is not dependent of the specific type of the argument that holds
330
/// the query parameters of the database connectors
331
#[cfg(feature = "mssql")]
332
impl<'a> IntoSql<'a> for &'a dyn QueryParameter<'a> {
333
61
    fn into_sql(self) -> ColumnData<'a> {
334
61
        self.as_sqlserver_param()
335
61
    }
336
}
337

            
338
//TODO Pending to review and see if it is necessary to apply something similar to the previous implementation.
339

            
340
impl<'a> QueryParameter<'a> for bool {
341
    #[cfg(feature = "postgres")]
342
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
343
        self
344
    }
345
    #[cfg(feature = "mssql")]
346
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
347
        ColumnData::Bit(Some(*self))
348
    }
349
    #[cfg(feature = "mysql")]
350
    fn as_mysql_param(&self) -> &dyn ToValue {
351
        self
352
    }
353
}
354
impl<'a> QueryParameter<'a> for i16 {
355
    #[cfg(feature = "postgres")]
356
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
357
        self
358
    }
359
    #[cfg(feature = "mssql")]
360
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
361
        ColumnData::I16(Some(*self))
362
    }
363
    #[cfg(feature = "mysql")]
364
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
365
        self
366
    }
367
}
368
impl<'a> QueryParameter<'a> for &i16 {
369
    #[cfg(feature = "postgres")]
370
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
371
        self
372
    }
373
    #[cfg(feature = "mssql")]
374
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
375
        ColumnData::I16(Some(**self))
376
    }
377
    #[cfg(feature = "mysql")]
378
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
379
        self
380
    }
381
}
382
impl<'a> QueryParameter<'a> for Option<i16> {
383
    #[cfg(feature = "postgres")]
384
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
385
        self
386
    }
387
    #[cfg(feature = "mssql")]
388
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
389
        ColumnData::I16(*self)
390
    }
391
    #[cfg(feature = "mysql")]
392
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
393
        self
394
    }
395
}
396
impl<'a> QueryParameter<'a> for Option<&i16> {
397
    #[cfg(feature = "postgres")]
398
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
399
        self
400
    }
401
    #[cfg(feature = "mssql")]
402
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
403
        ColumnData::I16(Some(*self.unwrap()))
404
    }
405
    #[cfg(feature = "mysql")]
406
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
407
        self
408
    }
409
}
410
impl<'a> QueryParameter<'a> for i32 {
411
    #[cfg(feature = "postgres")]
412
24
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
413
        self
414
24
    }
415
    #[cfg(feature = "mssql")]
416
24
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
417
24
        ColumnData::I32(Some(*self))
418
24
    }
419
    #[cfg(feature = "mysql")]
420
24
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
421
        self
422
24
    }
423
}
424
impl<'a> QueryParameter<'a> for &i32 {
425
    #[cfg(feature = "postgres")]
426
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
427
        self
428
    }
429
    #[cfg(feature = "mssql")]
430
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
431
        ColumnData::I32(Some(**self))
432
    }
433
    #[cfg(feature = "mysql")]
434
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
435
        self
436
    }
437
}
438
impl<'a> QueryParameter<'a> for Option<i32> {
439
    #[cfg(feature = "postgres")]
440
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
441
        self
442
    }
443
    #[cfg(feature = "mssql")]
444
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
445
        ColumnData::I32(*self)
446
    }
447
    #[cfg(feature = "mysql")]
448
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
449
        self
450
    }
451
}
452
impl<'a> QueryParameter<'a> for Option<&i32> {
453
    #[cfg(feature = "postgres")]
454
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
455
        self
456
    }
457
    #[cfg(feature = "mssql")]
458
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
459
        ColumnData::I32(Some(*self.unwrap()))
460
    }
461
    #[cfg(feature = "mysql")]
462
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
463
        self
464
    }
465
}
466
impl<'a> QueryParameter<'a> for f32 {
467
    #[cfg(feature = "postgres")]
468
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
469
        self
470
    }
471
    #[cfg(feature = "mssql")]
472
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
473
        ColumnData::F32(Some(*self))
474
    }
475
    #[cfg(feature = "mysql")]
476
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
477
        self
478
    }
479
}
480
impl<'a> QueryParameter<'a> for &f32 {
481
    #[cfg(feature = "postgres")]
482
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
483
        self
484
    }
485
    #[cfg(feature = "mssql")]
486
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
487
        ColumnData::F32(Some(**self))
488
    }
489
    #[cfg(feature = "mysql")]
490
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
491
        self
492
    }
493
}
494
impl<'a> QueryParameter<'a> for Option<f32> {
495
    #[cfg(feature = "postgres")]
496
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
497
        self
498
    }
499
    #[cfg(feature = "mssql")]
500
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
501
        ColumnData::F32(*self)
502
    }
503
    #[cfg(feature = "mysql")]
504
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
505
        self
506
    }
507
}
508
impl<'a> QueryParameter<'a> for Option<&f32> {
509
    #[cfg(feature = "postgres")]
510
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
511
        self
512
    }
513
    #[cfg(feature = "mssql")]
514
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
515
        ColumnData::F32(Some(
516
            *self.expect("Error on an f32 value on QueryParameter<'_>"),
517
        ))
518
    }
519
    #[cfg(feature = "mysql")]
520
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
521
        self
522
    }
523
}
524
impl<'a> QueryParameter<'a> for f64 {
525
    #[cfg(feature = "postgres")]
526
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
527
        self
528
    }
529
    #[cfg(feature = "mssql")]
530
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
531
        ColumnData::F64(Some(*self))
532
    }
533
    #[cfg(feature = "mysql")]
534
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
535
        self
536
    }
537
}
538
impl<'a> QueryParameter<'a> for &f64 {
539
    #[cfg(feature = "postgres")]
540
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
541
        self
542
    }
543
    #[cfg(feature = "mssql")]
544
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
545
        ColumnData::F64(Some(**self))
546
    }
547
    #[cfg(feature = "mysql")]
548
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
549
        self
550
    }
551
}
552
impl<'a> QueryParameter<'a> for Option<f64> {
553
    #[cfg(feature = "postgres")]
554
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
555
        self
556
    }
557
    #[cfg(feature = "mssql")]
558
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
559
        ColumnData::F64(*self)
560
    }
561
    #[cfg(feature = "mysql")]
562
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
563
        self
564
    }
565
}
566
impl<'a> QueryParameter<'a> for Option<&f64> {
567
    #[cfg(feature = "postgres")]
568
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
569
        self
570
    }
571
    #[cfg(feature = "mssql")]
572
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
573
        ColumnData::F64(Some(
574
            *self.expect("Error on an f64 value on QueryParameter<'_>"),
575
        ))
576
    }
577
    #[cfg(feature = "mysql")]
578
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
579
        self
580
    }
581
}
582
impl<'a> QueryParameter<'a> for i64 {
583
    #[cfg(feature = "postgres")]
584
7
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
585
        self
586
7
    }
587
    #[cfg(feature = "mssql")]
588
7
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
589
7
        ColumnData::I64(Some(*self))
590
7
    }
591
    #[cfg(feature = "mysql")]
592
7
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
593
        self
594
7
    }
595
}
596
impl<'a> QueryParameter<'a> for &i64 {
597
    #[cfg(feature = "postgres")]
598
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
599
        self
600
    }
601
    #[cfg(feature = "mssql")]
602
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
603
        ColumnData::I64(Some(**self))
604
    }
605
    #[cfg(feature = "mysql")]
606
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
607
        self
608
    }
609
}
610
impl<'a> QueryParameter<'a> for Option<i64> {
611
    #[cfg(feature = "postgres")]
612
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
613
        self
614
    }
615
    #[cfg(feature = "mssql")]
616
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
617
        ColumnData::I64(*self)
618
    }
619
    #[cfg(feature = "mysql")]
620
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
621
        self
622
    }
623
}
624
impl<'a> QueryParameter<'a> for Option<&i64> {
625
    #[cfg(feature = "postgres")]
626
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
627
        self
628
    }
629
    #[cfg(feature = "mssql")]
630
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
631
        ColumnData::I64(Some(*self.unwrap()))
632
    }
633
    #[cfg(feature = "mysql")]
634
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
635
        self
636
    }
637
}
638
impl<'a> QueryParameter<'a> for String {
639
    #[cfg(feature = "postgres")]
640
28
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
641
        self
642
28
    }
643
    #[cfg(feature = "mssql")]
644
28
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
645
28
        ColumnData::String(Some(std::borrow::Cow::Owned(self.to_owned())))
646
28
    }
647
    #[cfg(feature = "mysql")]
648
28
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
649
        self
650
28
    }
651
}
652
impl<'a> QueryParameter<'a> for &String {
653
    #[cfg(feature = "postgres")]
654
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
655
        self
656
    }
657
    #[cfg(feature = "mssql")]
658
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
659
        ColumnData::String(Some(std::borrow::Cow::Borrowed(self)))
660
    }
661
    #[cfg(feature = "mysql")]
662
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
663
        self
664
    }
665
}
666
impl<'a> QueryParameter<'a> for Option<String> {
667
    #[cfg(feature = "postgres")]
668
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
669
        self
670
    }
671
    #[cfg(feature = "mssql")]
672
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
673
        match self {
674
            Some(string) => ColumnData::String(Some(std::borrow::Cow::Owned(string.to_owned()))),
675
            None => ColumnData::String(None),
676
        }
677
    }
678
    #[cfg(feature = "mysql")]
679
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
680
        self
681
    }
682
}
683
impl<'a> QueryParameter<'a> for Option<&String> {
684
    #[cfg(feature = "postgres")]
685
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
686
        self
687
    }
688
    #[cfg(feature = "mssql")]
689
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
690
        match self {
691
            Some(string) => ColumnData::String(Some(std::borrow::Cow::Borrowed(string))),
692
            None => ColumnData::String(None),
693
        }
694
    }
695
    #[cfg(feature = "mysql")]
696
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
697
        self
698
    }
699
}
700
impl<'a> QueryParameter<'a> for &'_ str {
701
    #[cfg(feature = "postgres")]
702
3
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
703
        self
704
3
    }
705
    #[cfg(feature = "mssql")]
706
2
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
707
2
        ColumnData::String(Some(std::borrow::Cow::Borrowed(*self)))
708
2
    }
709
    #[cfg(feature = "mysql")]
710
2
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
711
        self
712
2
    }
713
}
714
impl<'a> QueryParameter<'a> for Option<&'_ str> {
715
    #[cfg(feature = "postgres")]
716
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
717
        self
718
    }
719
    #[cfg(feature = "mssql")]
720
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
721
        match *self {
722
            Some(str) => ColumnData::String(Some(std::borrow::Cow::Borrowed(str))),
723
            None => ColumnData::String(None),
724
        }
725
    }
726
    #[cfg(feature = "mysql")]
727
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
728
        self
729
    }
730
}
731
impl<'a> QueryParameter<'a> for NaiveDate {
732
    #[cfg(feature = "postgres")]
733
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
734
        self
735
    }
736
    #[cfg(feature = "mssql")]
737
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
738
        self.into_sql()
739
    }
740
    #[cfg(feature = "mysql")]
741
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
742
        self
743
    }
744
}
745
impl<'a> QueryParameter<'a> for Option<NaiveDate> {
746
    #[cfg(feature = "postgres")]
747
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
748
        self
749
    }
750
    #[cfg(feature = "mssql")]
751
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
752
        self.into_sql()
753
    }
754
    #[cfg(feature = "mysql")]
755
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
756
        self
757
    }
758
}
759
impl<'a> QueryParameter<'a> for NaiveTime {
760
    #[cfg(feature = "postgres")]
761
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
762
        self
763
    }
764
    #[cfg(feature = "mssql")]
765
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
766
        self.into_sql()
767
    }
768
    #[cfg(feature = "mysql")]
769
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
770
        self
771
    }
772
}
773
impl<'a> QueryParameter<'a> for Option<NaiveTime> {
774
    #[cfg(feature = "postgres")]
775
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
776
        self
777
    }
778
    #[cfg(feature = "mssql")]
779
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
780
        self.into_sql()
781
    }
782
    #[cfg(feature = "mysql")]
783
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
784
        self
785
    }
786
}
787
impl<'a> QueryParameter<'a> for NaiveDateTime {
788
    #[cfg(feature = "postgres")]
789
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
790
        self
791
    }
792
    #[cfg(feature = "mssql")]
793
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
794
        self.into_sql()
795
    }
796
    #[cfg(feature = "mysql")]
797
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
798
        self
799
    }
800
}
801
impl<'a> QueryParameter<'a> for Option<NaiveDateTime> {
802
    #[cfg(feature = "postgres")]
803
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
804
        self
805
    }
806
    #[cfg(feature = "mssql")]
807
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
808
        self.into_sql()
809
    }
810
    #[cfg(feature = "mysql")]
811
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
812
        self
813
    }
814
}
815

            
816
//TODO pending
817
impl<'a> QueryParameter<'a> for DateTime<FixedOffset> {
818
    #[cfg(feature = "postgres")]
819
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
820
        self
821
    }
822
    #[cfg(feature = "mssql")]
823
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
824
        self.into_sql()
825
    }
826
    #[cfg(feature = "mysql")]
827
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
828
        todo!()
829
    }
830
}
831

            
832
impl<'a> QueryParameter<'a> for Option<DateTime<FixedOffset>> {
833
    #[cfg(feature = "postgres")]
834
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
835
        self
836
    }
837
    #[cfg(feature = "mssql")]
838
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
839
        self.into_sql()
840
    }
841
    #[cfg(feature = "mysql")]
842
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
843
        todo!()
844
    }
845
}
846

            
847
impl<'a> QueryParameter<'a> for DateTime<Utc> {
848
    #[cfg(feature = "postgres")]
849
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
850
        self
851
    }
852
    #[cfg(feature = "mssql")]
853
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
854
        self.into_sql()
855
    }
856
    #[cfg(feature = "mysql")]
857
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
858
        todo!()
859
    }
860
}
861

            
862
impl<'a> QueryParameter<'a> for Option<DateTime<Utc>> {
863
    #[cfg(feature = "postgres")]
864
    fn as_postgres_param(&self) -> &(dyn ToSql + Sync) {
865
        self
866
    }
867
    #[cfg(feature = "mssql")]
868
    fn as_sqlserver_param(&self) -> ColumnData<'_> {
869
        self.into_sql()
870
    }
871
    #[cfg(feature = "mysql")]
872
    fn as_mysql_param(&self) -> &dyn mysql_async::prelude::ToValue {
873
        todo!()
874
    }
875
}