sqlx_askama_template/
lib.rs1#![doc = include_str!("../README.md")]
2use sqlx::{Arguments, Database, Execute};
3pub use sqlx_askama_template_macro::*;
4use std::cell::RefCell;
5
6pub struct SqlTemplateExecute<'q, DB: Database> {
8 pub(crate) sql: &'q str,
10 pub(crate) arguments: Option<DB::Arguments<'q>>,
12 pub(crate) persistent: bool,
14}
15impl<DB: Database> SqlTemplateExecute<'_, DB> {
16 pub fn set_persistent(&mut self, persistent: bool) {
17 self.persistent = persistent;
18 }
19}
20impl<'q, DB: Database> Execute<'q, DB> for SqlTemplateExecute<'q, DB> {
21 fn sql(&self) -> &'q str {
23 self.sql
24 }
25
26 fn statement(&self) -> Option<&DB::Statement<'q>> {
28 None
29 }
30
31 fn take_arguments(&mut self) -> Result<Option<DB::Arguments<'q>>, sqlx::error::BoxDynError> {
33 Ok(self.arguments.take())
34 }
35
36 fn persistent(&self) -> bool {
38 self.persistent
39 }
40}
41
42pub struct TemplateArg<'q, DB: Database> {
46 error: RefCell<Option<sqlx::error::BoxDynError>>,
48 arguments: RefCell<Option<DB::Arguments<'q>>>,
50}
51
52impl<DB: Database> Default for TemplateArg<'_, DB> {
53 fn default() -> Self {
55 TemplateArg {
56 error: RefCell::new(None),
57 arguments: RefCell::new(None),
58 }
59 }
60}
61
62impl<'q, DB: Database> TemplateArg<'q, DB> {
63 pub fn encode<T>(&self, t: T) -> String
71 where
72 T: sqlx::Encode<'q, DB> + sqlx::Type<DB> + 'q,
73 {
74 let mut err = self.error.borrow_mut();
75 let mut arguments = self.arguments.borrow_mut().take().unwrap_or_default();
76
77 if let Err(e) = arguments.add(t) {
78 if err.is_none() {
79 *err = Some(e);
80 }
81 }
82
83 let mut placeholder = String::new();
84 if let Err(e) = arguments.format_placeholder(&mut placeholder) {
85 if err.is_none() {
86 *err = Some(Box::new(e));
87 }
88 }
89
90 *self.arguments.borrow_mut() = Some(arguments);
91 placeholder
92 }
93
94 pub fn encode_list<T>(&self, args: impl Iterator<Item = T>) -> String
102 where
103 T: sqlx::Encode<'q, DB> + sqlx::Type<DB> + 'q,
104 {
105 let mut err = self.error.borrow_mut();
106 let mut arguments = self.arguments.borrow_mut().take().unwrap_or_default();
107 let mut placeholder = String::new();
108 placeholder.push('(');
109
110 for arg in args {
111 if let Err(e) = arguments.add(arg) {
112 if err.is_none() {
113 *err = Some(e);
114 }
115 }
116
117 if let Err(e) = arguments.format_placeholder(&mut placeholder) {
118 if err.is_none() {
119 *err = Some(Box::new(e));
120 }
121 }
122 placeholder.push(',');
123 }
124
125 if placeholder.ends_with(",") {
126 placeholder.pop();
127 }
128 placeholder.push(')');
129
130 *self.arguments.borrow_mut() = Some(arguments);
131 placeholder
132 }
133
134 pub fn get_err(&self) -> Option<sqlx::error::BoxDynError> {
136 self.error.borrow_mut().take()
137 }
138
139 pub fn get_arguments(&self) -> Option<DB::Arguments<'q>> {
141 self.arguments.borrow_mut().take()
142 }
143}
144
145pub trait SqlTemplate<'q, DB>: Sized
149where
150 DB: Database,
151{
152 fn render_sql(self) -> Result<(String, Option<DB::Arguments<'q>>), askama::Error>;
154
155 fn render_execute_able(
157 self,
158 sql_buffer: &'q mut String,
159 ) -> Result<SqlTemplateExecute<'q, DB>, askama::Error> {
160 let (sql, arguments) = self.render_sql()?;
161 *sql_buffer = sql;
162 Ok(SqlTemplateExecute {
163 sql: sql_buffer,
164
165 arguments,
166
167 persistent: true,
168 })
169 }
170}