pub trait SqlTemplate<'q, DB>:
Sized
+ Clone
+ 'qwhere
DB: Database,{
// Required method
fn render_sql_with_encode_placeholder_fn(
self,
f: Option<fn(usize, &mut String)>,
sql_buffer: &mut String,
) -> Result<Option<DB::Arguments<'q>>, Error>;
// Provided methods
fn render_sql(self) -> Result<(String, Option<DB::Arguments<'q>>), Error> { ... }
fn render_executable(
self,
sql_buffer: &'q mut String,
) -> Result<SqlTemplateExecute<'q, DB>, Error> { ... }
fn render_db_adapter_manager(
self,
_sql_buff: &'q mut String,
) -> DBAdapterManager<'q, DB, Self> { ... }
fn adapter_render(self) -> DBAdapterManager<'q, DB, Self> { ... }
}Expand description
SQL template trait
Defines basic operations for rendering SQL from templates
Required Methods§
Sourcefn render_sql_with_encode_placeholder_fn(
self,
f: Option<fn(usize, &mut String)>,
sql_buffer: &mut String,
) -> Result<Option<DB::Arguments<'q>>, Error>
fn render_sql_with_encode_placeholder_fn( self, f: Option<fn(usize, &mut String)>, sql_buffer: &mut String, ) -> Result<Option<DB::Arguments<'q>>, Error>
Renders the SQL template using a custom placeholder encoding function
Writes the rendered SQL to the provided buffer and handles parameter encoding. The placeholder function (if provided) formats parameter placeholders (e.g., $1, ?) based on their index.
§Parameters
f: Optional function to format parameter placeholders (receives index and buffer)sql_buffer: Mutable string buffer to store the rendered SQL
§Returns
Encoded database arguments (None if no parameters) or an error if rendering fails
Provided Methods§
Sourcefn render_sql(self) -> Result<(String, Option<DB::Arguments<'q>>), Error>
fn render_sql(self) -> Result<(String, Option<DB::Arguments<'q>>), Error>
Renders SQL template and returns query string with parameters
Examples found in repository?
158fn render_complex_sql() {
159 let data = QueryData {
160 arg1: 42,
161 _arg1: 123,
162 arg2: "value".to_string(),
163 arg3: "reference",
164 arg4: vec![12, 12, 55, 66],
165 arg5: HashMap::from_iter([(0, 2), (1, 2), (2, 3)]),
166 arg6: 1,
167 };
168
169 let (sql, arg) =
170 <&QueryData<'_, i32> as SqlTemplate<'_, sqlx::Postgres>>::render_sql(&data).unwrap();
171
172 assert_eq!(arg.unwrap().len(), 18);
173 println!("----{sql}----");
174
175 let data = ComplexQuery {
176 filter_names: vec!["name1", "name2"],
177 limit: 10,
178 min_age: Some(18),
179 order_field: "id",
180 };
181
182 let (sql, arg) =
183 <&ComplexQuery<'_> as SqlTemplate<'_, sqlx::Postgres>>::render_sql(&data).unwrap();
184
185 assert_eq!(arg.unwrap().len(), 6);
186 println!("----{sql}----");
187}Sourcefn render_executable(
self,
sql_buffer: &'q mut String,
) -> Result<SqlTemplateExecute<'q, DB>, Error>
fn render_executable( self, sql_buffer: &'q mut String, ) -> Result<SqlTemplateExecute<'q, DB>, Error>
Renders SQL template and returns executable query result
Examples found in repository?
25async fn simple_query() -> Result<(), Error> {
26 let users = vec![
27 User {
28 id: 1,
29 name: "admin".to_string(),
30 },
31 User {
32 id: 99999_i64,
33 name: "super man".to_string(),
34 },
35 ];
36
37 let user_query = UserQuery {
38 user_id: 1,
39 user_name: "admin".to_string(),
40 };
41 //pg
42
43 let pool = sqlx::PgPool::connect("postgres://postgres:postgres@localhost/postgres").await?;
44 let mut sql_buff = String::new();
45 let execute = user_query.render_executable(&mut sql_buff)?;
46
47 let rows = pool.fetch_all(execute).await?;
48 let mut db_users = Vec::new();
49 for row in &rows {
50 db_users.push(User::from_row(row)?);
51 }
52 assert_eq!(db_users, users);
53
54 //sqlite+any
55 install_default_drivers();
56 let pool = AnyPool::connect("sqlite://db.file?mode=memory").await?;
57 let mut sql_buff = String::new();
58 let rows = user_query
59 .render_executable(&mut sql_buff)?
60 .fetch_all(&pool)
61 .await?;
62
63 let mut db_users = Vec::new();
64 for row in &rows {
65 db_users.push(User::from_row(row)?);
66 }
67 assert_eq!(db_users, users);
68
69 //mysql
70
71 let pool = MySqlPool::connect("mysql://root:root@localhost/mysql").await?;
72
73 let db_users: Vec<User> = user_query
74 .adapter_render()
75 .set_persistent(false)
76 .fetch_all_as(&pool)
77 .await?;
78
79 assert_eq!(db_users, users);
80 Ok(())
81}fn render_db_adapter_manager( self, _sql_buff: &'q mut String, ) -> DBAdapterManager<'q, DB, Self>
use adapter_render instead
Sourcefn adapter_render(self) -> DBAdapterManager<'q, DB, Self>
fn adapter_render(self) -> DBAdapterManager<'q, DB, Self>
Creates a database adapter manager for the template
Provides an adapter pattern interface for managing template rendering in database-specific scenarios.
§Returns
A new DBAdapterManager instance wrapping the template
Examples found in repository?
56async fn root(pool: State<AnyPool>) -> impl Responder {
57 // test count
58 let user_query = UserQuery {
59 user_id: 1,
60 user_name: "ntex",
61 };
62 let count = user_query.adapter_render().count(&*pool).await.unwrap();
63 println!("count: {count}");
64
65 let mut conn = pool.acquire().await.unwrap();
66 let users: Vec<User> = user_query
67 .adapter_render()
68 .fetch_all_as(&mut *conn)
69 .await
70 .unwrap();
71
72 Response::Ok().body(IndexHtml { users }.render().unwrap())
73}More examples
56async fn root(pool: Data<AnyPool>) -> impl actix_web::Responder {
57 // test count
58 let user_query = UserQuery {
59 user_id: 1,
60 user_name: "actix",
61 };
62 let count = user_query.adapter_render().count(&**pool).await.unwrap();
63 println!("count: {count}");
64
65 let mut conn = pool.acquire().await.unwrap();
66 let users: Vec<User> = user_query
67 .adapter_render()
68 .fetch_all_as(&mut *conn)
69 .await
70 .unwrap();
71
72 Html::new(IndexHtml { users }.render().unwrap())
73}25async fn simple_query() -> Result<(), Error> {
26 let users = vec![
27 User {
28 id: 1,
29 name: "admin".to_string(),
30 },
31 User {
32 id: 99999_i64,
33 name: "super man".to_string(),
34 },
35 ];
36
37 let user_query = UserQuery {
38 user_id: 1,
39 user_name: "admin".to_string(),
40 };
41 //pg
42
43 let pool = sqlx::PgPool::connect("postgres://postgres:postgres@localhost/postgres").await?;
44 let mut sql_buff = String::new();
45 let execute = user_query.render_executable(&mut sql_buff)?;
46
47 let rows = pool.fetch_all(execute).await?;
48 let mut db_users = Vec::new();
49 for row in &rows {
50 db_users.push(User::from_row(row)?);
51 }
52 assert_eq!(db_users, users);
53
54 //sqlite+any
55 install_default_drivers();
56 let pool = AnyPool::connect("sqlite://db.file?mode=memory").await?;
57 let mut sql_buff = String::new();
58 let rows = user_query
59 .render_executable(&mut sql_buff)?
60 .fetch_all(&pool)
61 .await?;
62
63 let mut db_users = Vec::new();
64 for row in &rows {
65 db_users.push(User::from_row(row)?);
66 }
67 assert_eq!(db_users, users);
68
69 //mysql
70
71 let pool = MySqlPool::connect("mysql://root:root@localhost/mysql").await?;
72
73 let db_users: Vec<User> = user_query
74 .adapter_render()
75 .set_persistent(false)
76 .fetch_all_as(&pool)
77 .await?;
78
79 assert_eq!(db_users, users);
80 Ok(())
81}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}58async fn test_adapter_query(url: &str) -> Result<(), Error> {
59 let data = vec![
60 User {
61 id: 1,
62 name: "admin".to_string(),
63 },
64 User {
65 id: 99999,
66 name: "super man".to_string(),
67 },
68 ];
69 // test count
70 let user_query = UserQuery {
71 user_id: 1,
72 user_name: "admin",
73 };
74 let pool = AnyPool::connect(url).await?;
75
76 let mut db_adatper = user_query.adapter_render();
77
78 let count = db_adatper.count(&pool).await?;
79 assert_eq!(2, count);
80
81 // test pagination
82 let user: Option<User> = user_query
83 .adapter_render()
84 .set_page(1, 1)
85 .fetch_optional_as(&pool)
86 .await?;
87 assert_eq!(data.first(), user.as_ref());
88 // println!("{user:?}");
89
90 let mut conn = pool.acquire().await?;
91 let user: Vec<User> = user_query
92 .adapter_render()
93 .set_page(1, 2)
94 .fetch_all_as(&mut *conn)
95 .await?;
96 assert_eq!(data[1..], user);
97 // println!("{user:?}");
98
99 let page_info = user_query.adapter_render().count_page(1, &pool).await?;
100 assert_eq!(PageInfo::new(2, 1), page_info);
101 // println!("{page_info:?}");
102 //fecth
103 let mut tx = pool.begin().await?;
104
105 let rows = UserQuery {
106 user_id: 1,
107 user_name: "admin",
108 }
109 .adapter_render()
110 .fetch_all(&mut *tx)
111 .await?;
112 assert_eq!(2, rows.len());
113 //println!("{:?}", rows.len());
114 let row = UserQuery {
115 user_id: 1,
116 user_name: "admin",
117 }
118 .adapter_render()
119 .fetch_optional(&mut *tx)
120 .await?;
121 assert!(row.is_some());
122 let row = UserQuery {
123 user_id: 1,
124 user_name: "admin",
125 }
126 .adapter_render()
127 .fetch_one(&mut *tx)
128 .await?;
129 assert_eq!(2, row.columns().len());
130 // fetch_as
131 let users: Vec<User> = user_query.adapter_render().fetch_all_as(&pool).await?;
132 assert_eq!(data, users);
133 //println!("{:?}", users);
134
135 let u: Option<User> = UserQuery {
136 user_id: 1,
137 user_name: "admin",
138 }
139 .adapter_render()
140 .fetch_optional_as(&mut *tx)
141 .await?;
142 assert_eq!(data.first(), u.as_ref());
143 let u: User = UserQuery {
144 user_id: 1,
145 user_name: "admin",
146 }
147 .adapter_render()
148 .fetch_one_as(&mut *tx)
149 .await?;
150 assert_eq!(data.first(), Some(&u));
151
152 // stream
153 let mut query = user_query.adapter_render();
154 {
155 let stream = query.fetch(&mut *tx);
156 pin_mut!(stream);
157 while let Some(row) = stream.try_next().await? {
158 assert_eq!(2, row.columns().len());
159 }
160 }
161
162 tx.rollback().await?;
163
164 Ok(())
165}
166#[axum::debug_handler]
167async fn root(State(pool): State<AnyPool>) -> impl axum::response::IntoResponse {
168 test_adapter_query("sqlite://db.file?mode=memory")
169 .await
170 .unwrap();
171 // test count
172 let user_query = UserQuery {
173 user_id: 1,
174 user_name: "axum",
175 };
176 let count = user_query.adapter_render().count(&pool).await.unwrap();
177 println!("count: {count}");
178
179 let mut conn = pool.acquire().await.unwrap();
180 let rows = user_query
181 .adapter_render()
182 .fetch_all_as(&mut *conn)
183 .await
184 .unwrap();
185 Html(IndexHtml { users: rows }.render().unwrap())
186}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.