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 let (get_db_type, _get_conn) = pool.backend_db().await?;
34 assert_eq!(db_type.backend_name(), get_db_type.backend_name());
35
36 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 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 let pool = MySqlPool::connect(url).await?;
50 let (get_db_type, _get_conn) = pool.backend_db().await?;
52 assert_eq!(DBType::MySQL.backend_name(), get_db_type.backend_name());
53
54 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 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 let pool = PgPool::connect(url).await?;
67 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 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 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 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 let pool = SqlitePool::connect(url).await?;
101 let (get_db_type, _get_conn) = pool.backend_db().await?;
103 assert_eq!(DBType::SQLite.backend_name(), get_db_type.backend_name());
104
105 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 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 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 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 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 let page_info = user_query.adapter_render().count_page(1, &pool).await?;
164 assert_eq!(PageInfo::new(2, 1), page_info);
165 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 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 let users: Vec<User> = user_query.adapter_render().fetch_all_as(&pool).await?;
196 assert_eq!(data, users);
197 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 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 ];
244 test_backend(urls).await?;
245
246 Ok(())
247}