1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120


/*
 * @Author: plucky
 * @Date: 2022-10-21 16:53:21
 * @LastEditTime: 2023-12-15 15:18:32
 * @Description: 
 */

//! Derive macro for sqlx to implement Create, Read, Update, and Delete (CRUD) methods.
//! # Use
//! adding the following to your project's Cargo.toml:
//! ```toml
//! [dependencies]
//! co-orm = { virsion = "0.3", features = ["mysql"] }
//! sqlx = { version = "0.7", features = ["mysql"] }
//! ```
//! features: mysql, postgres, sqlite, mssql
//! 
//! # Examples 
//! ``` no_run,ignore
//! use co_orm::{Crud, FromRow};
//! 
//! #[derive(Debug, Crud, FromRow)]
//! #[co_orm(rename = "users")] // rename table name
//! pub struct User {
//!     // #[co_orm(id)] // default first field is primary key
//!     #[co_orm(seq)] // sequence field, insert will ignore this field
//!     pub id: u64,
//!     #[co_orm(rename = "name")] // rename field name
//!     #[co_orm(by)] // generate query_by_field,update_by_field,delete_by_field
//!     pub name: String,
//!     #[co_orm(update)] // generate method update_xxx. 
//!     pub password: String,
//!     #[co_orm(skip)] // ignore field
//!     pub addr: Option<String>,
//!     // #[co_orm(skip_insert)] // insert will skip this field.
//!     // pub update_at: Option<NaiveDateTime>,
//! }
//! 
//! // use crud
//! let u = User::get(&pool, 1).await;
//! println!("get {:?}", u);
//! let u = User::get_by(&pool, "where id=?", sql_args!(1)).await;
//! println!("get_by {:?}", u);
//! ```

pub use co_orm_macros::Crud;
pub use co_orm_macros::FromRow;


/// sqlx::query_as
/// ``` no_run,ignore
/// query_as!(User, "select * from users where name = ?", name).fetch_one(&pool).await
/// ```
#[macro_export]
macro_rules! query_as (
    ($out_struct:path, $query:expr) => ( {
        sqlx::query_as::<_, $out_struct>($query)
    });
    ($out_struct:path, $query:expr, $($args:expr),*) => ( {
        sqlx::query_as::<_, $out_struct>($query)
        $(.bind($args))*
    })
);

/// sqlx::query
/// ``` no_run,ignore
/// query!("insert into users (name, password) values (?,?)", name, password).execute(&pool).await
/// ```
#[macro_export]
macro_rules! query (
    ($query:expr) => ( {
        sqlx::query($query)
    });
    ($query:expr, $($args:expr),*) => ( {
        sqlx::query($query)
        $(.bind($args))*
    })
);

/// # Examples
///
/// ```no_run,ignore
/// 
/// let args = sql_args!(&name, age);
/// ```
#[macro_export]
macro_rules! sql_args {

    // ($sql:expr) => {
    //     sql_args!($sql,);
    // };
    
    ($($args:expr),*) => {{
        use sqlx::Arguments;
        #[cfg(feature = "mysql")]{
            let mut sqlargs = sqlx::mysql::MySqlArguments::default();
            $(sqlargs.add($args);)*
            sqlargs
        }
        #[cfg(feature = "postgres")]{
            let mut sqlargs = sqlx::postgres::PgArguments::default();
            $(sqlargs.add($args);)*
            sqlargs
        }
        #[cfg(feature = "mssql")]{
            let mut sqlargs = sqlx::mysql::MySqlArguments::default();
            $(sqlargs.add($args);)*
            sqlargs
        }
        #[cfg(feature = "sqlite")]{
            let mut sqlargs = sqlx::sqlite::SqliteArguments::default();
            $(sqlargs.add($args);)*
            sqlargs
        }
        // let mut sqlargs = sqlx::any::AnyArguments::default();
       
    }};
}