Skip to main content

example_adapter/
example_adapter.rs

1use futures_util::pin_mut;
2use futures_util::stream::TryStreamExt;
3use sqlx::postgres::PgListener;
4use sqlx::{AnyPool, Error, any::install_default_drivers};
5use sqlx::{MySqlPool, PgPool, Row, SqlitePool};
6
7use sqlx_askama_template::{BackendDB, DatabaseDialect, PageInfo, SqlTemplate};
8
9use sqlx_askama_template::DBType;
10#[derive(sqlx::prelude::FromRow, PartialEq, Eq, Debug)]
11struct User {
12    id: i64,
13    name: String,
14}
15#[derive(SqlTemplate)]
16#[template(source = r#"
17    select {{e(user_id)}} as id,{{e(user_name)}} as name
18    union all 
19    {%- let id=99999_i64 %}
20    {%- let name="super man" %}
21    select {{et(id)}} as id,{{et(name)}} as name
22"#)]
23pub struct UserQuery<'a> {
24    pub user_id: i64,
25    pub user_name: &'a str,
26}
27
28async fn test_backend(urls: Vec<(DBType, &str)>) -> Result<(), Error> {
29    install_default_drivers();
30    for (db_type, url) in urls {
31        let pool = AnyPool::connect(url).await?;
32        // pool
33        let (get_db_type, _get_conn) = pool.backend_db().await?;
34        assert_eq!(db_type.backend_name(), get_db_type.backend_name());
35
36        // connection
37        let mut conn = pool.acquire().await?;
38        let (get_db_type, _get_conn) = conn.backend_db().await?;
39        assert_eq!(db_type.backend_name(), get_db_type.backend_name());
40
41        // tx
42        let mut conn = pool.begin().await?;
43        let (get_db_type, _get_conn) = conn.backend_db().await?;
44        assert_eq!(db_type.backend_name(), get_db_type.backend_name());
45
46        match db_type {
47            DBType::MySQL => {
48                //mysql  DBType::MySQL, "mysql://root:root@localhost/mysql"
49                let pool = MySqlPool::connect(url).await?;
50                // pool
51                let (get_db_type, _get_conn) = pool.backend_db().await?;
52                assert_eq!(DBType::MySQL.backend_name(), get_db_type.backend_name());
53
54                // connection
55                let mut conn = pool.acquire().await?;
56                let (get_db_type, _get_conn) = conn.backend_db().await?;
57                assert_eq!(DBType::MySQL.backend_name(), get_db_type.backend_name());
58
59                //
60                let mut conn = pool.begin().await?;
61                let (get_db_type, _get_conn) = conn.backend_db().await?;
62                assert_eq!(DBType::MySQL.backend_name(), get_db_type.backend_name());
63            }
64            DBType::PostgreSQL => {
65                //pg
66                let pool = PgPool::connect(url).await?;
67                // pool
68                let (get_db_type, _get_conn) = pool.backend_db().await?;
69                assert_eq!(
70                    DBType::PostgreSQL.backend_name(),
71                    get_db_type.backend_name()
72                );
73
74                // connection
75                let mut conn = pool.acquire().await?;
76                let (get_db_type, _get_conn) = conn.backend_db().await?;
77                assert_eq!(
78                    DBType::PostgreSQL.backend_name(),
79                    get_db_type.backend_name()
80                );
81
82                // tx
83                let mut conn = pool.begin().await?;
84                let (get_db_type, _get_conn) = conn.backend_db().await?;
85                assert_eq!(
86                    DBType::PostgreSQL.backend_name(),
87                    get_db_type.backend_name()
88                );
89
90                // listener
91                let mut listener = PgListener::connect(url).await?;
92                let (get_db_type, _get_conn) = listener.backend_db().await?;
93                assert_eq!(
94                    DBType::PostgreSQL.backend_name(),
95                    get_db_type.backend_name()
96                );
97            }
98            DBType::SQLite => {
99                //sqlite DBType::SQLite, "sqlite://db.file?mode=memory"
100                let pool = SqlitePool::connect(url).await?;
101                // pool
102                let (get_db_type, _get_conn) = pool.backend_db().await?;
103                assert_eq!(DBType::SQLite.backend_name(), get_db_type.backend_name());
104
105                // connection
106                let mut conn = pool.acquire().await?;
107                let (get_db_type, _get_conn) = conn.backend_db().await?;
108                assert_eq!(DBType::SQLite.backend_name(), get_db_type.backend_name());
109
110                // tx
111                let mut conn = pool.begin().await?;
112                let (get_db_type, _get_conn) = conn.backend_db().await?;
113                assert_eq!(DBType::SQLite.backend_name(), get_db_type.backend_name());
114            }
115        }
116        test_adapter_query(url).await?;
117    }
118
119    Ok(())
120}
121
122async fn test_adapter_query(url: &str) -> Result<(), Error> {
123    let data = vec![
124        User {
125            id: 1,
126            name: "admin".to_string(),
127        },
128        User {
129            id: 99999,
130            name: "super man".to_string(),
131        },
132    ];
133    //  test count
134    let user_query = UserQuery {
135        user_id: 1,
136        user_name: "admin",
137    };
138    let pool = AnyPool::connect(url).await?;
139
140    let mut db_adatper = user_query.adapter_render();
141
142    let count = db_adatper.count(&pool).await?;
143    assert_eq!(2, count);
144
145    // test pagination
146    let user: Option<User> = user_query
147        .adapter_render()
148        .set_page(1, 1)
149        .fetch_optional_as(&pool)
150        .await?;
151    assert_eq!(data.first(), user.as_ref());
152    // println!("{user:?}");
153
154    let mut conn = pool.acquire().await?;
155    let user: Vec<User> = user_query
156        .adapter_render()
157        .set_page(1, 2)
158        .fetch_all_as(&mut *conn)
159        .await?;
160    assert_eq!(data[1..], user);
161    // println!("{user:?}");
162
163    let page_info = user_query.adapter_render().count_page(1, &pool).await?;
164    assert_eq!(PageInfo::new(2, 1), page_info);
165    // println!("{page_info:?}");
166    //fecth
167    let mut tx = pool.begin().await?;
168
169    let rows = UserQuery {
170        user_id: 1,
171        user_name: "admin",
172    }
173    .adapter_render()
174    .fetch_all(&mut *tx)
175    .await?;
176    assert_eq!(2, rows.len());
177    //println!("{:?}", rows.len());
178    let row = UserQuery {
179        user_id: 1,
180        user_name: "admin",
181    }
182    .adapter_render()
183    .fetch_optional(&mut *tx)
184    .await?;
185    assert!(row.is_some());
186    let row = UserQuery {
187        user_id: 1,
188        user_name: "admin",
189    }
190    .adapter_render()
191    .fetch_one(&mut *tx)
192    .await?;
193    assert_eq!(2, row.columns().len());
194    // fetch_as
195    let users: Vec<User> = user_query.adapter_render().fetch_all_as(&pool).await?;
196    assert_eq!(data, users);
197    //println!("{:?}", users);
198
199    let u: Option<User> = UserQuery {
200        user_id: 1,
201        user_name: "admin",
202    }
203    .adapter_render()
204    .fetch_optional_as(&mut *tx)
205    .await?;
206    assert_eq!(data.first(), u.as_ref());
207    let u: User = UserQuery {
208        user_id: 1,
209        user_name: "admin",
210    }
211    .adapter_render()
212    .fetch_one_as(&mut *tx)
213    .await?;
214    assert_eq!(data.first(), Some(&u));
215
216    // stream
217    let mut query = user_query.adapter_render();
218    {
219        let stream = query.fetch(&mut *tx);
220        pin_mut!(stream);
221        while let Some(row) = stream.try_next().await? {
222            assert_eq!(2, row.columns().len());
223        }
224    }
225
226    tx.rollback().await?;
227
228    Ok(())
229}
230#[tokio::main]
231async fn main() -> Result<(), Error> {
232    unsafe {
233        std::env::set_var("RUST_LOG", "sqlx_askama_template=DEBUG");
234    }
235    env_logger::init();
236    let urls = vec![
237        (
238            DBType::PostgreSQL,
239            "postgres://postgres:postgres@localhost/postgres",
240        ),
241        (DBType::SQLite, "sqlite://db.file?mode=memory"),
242        //(DBType::MySQL, "mysql://root:root@localhost/mysql"),
243    ];
244    test_backend(urls).await?;
245
246    Ok(())
247}