1use crate::error::LunaOrmError;
2use crate::sql_executor::SqlExecutor;
3use crate::sql_generator::SqlGenerator;
4use crate::LunaOrmResult;
5
6use luna_orm_macro::timed;
7use luna_orm_trait::*;
8use std::fmt::Debug;
9use tracing::{debug, instrument};
10
11pub trait CommandExecutor: SqlExecutor + Debug {
12 type G: SqlGenerator + Sync + Debug;
13
14 fn get_generator(&self) -> &Self::G;
15
16 async fn select<SE>(
17 &mut self,
18 primary: &dyn Primary,
19 selection: &dyn Selection,
20 ) -> LunaOrmResult<Option<SE>>
21 where
22 SE: SelectedEntity + Send + Unpin,
23 {
24 debug!(target: "luna_orm", command = "select", primary = ?primary, selection = ?selection);
25 let sql = self.get_generator().get_select_sql(selection, primary);
26 debug!(target: "luna_orm", command = "select", sql = sql);
27 let args = primary.any_arguments();
28 let result: Option<SE> = self.fetch_optional(&sql, args).await?;
29 debug!(target: "luna_orm", command = "select", result = ?result);
30 return Ok(result);
31 }
32
33 async fn create<'a>(&mut self, entity: &'a mut dyn Entity) -> LunaOrmResult<bool> {
34 debug!(target: "luna_orm2", command = "create", entity = ?entity);
35 let sql = self.get_generator().get_create_sql(entity);
36 debug!(target: "luna_orm", command = "create", sql = sql);
37 let args = entity.any_arguments_of_insert();
38 if entity.get_auto_increment_field().is_some() {
39 let last_row_id: LastRowId = self.fetch_one(&sql, args).await?;
40 entity.set_auto_increment_field(Some(last_row_id.id));
41 } else {
42 self.execute(&sql, args).await?;
43 }
44 debug!(target: "luna_orm", command = "create", result = ?entity);
45 return Ok(true);
46 }
47
48 #[timed]
49 async fn insert(&mut self, entity: &dyn Entity) -> LunaOrmResult<bool> {
50 debug!(target: "luna_orm", command = "insert", entity = ?entity);
51 let sql = self.get_generator().get_insert_sql(entity);
52 debug!(target: "luna_orm", command = "insert", sql = sql);
53 let args = entity.any_arguments_of_insert();
54 let result = self.execute(&sql, args).await?;
55 debug!(target: "luna_orm", command = "insert", result = ?result);
56 return Ok(result.rows_affected() > 0);
57 }
58
59 async fn upsert(&mut self, entity: &dyn Entity) -> LunaOrmResult<bool> {
60 debug!(target: "luna_orm", command = "upsert", entity = ?entity);
61 let sql = self.get_generator().get_upsert_sql(entity);
62 debug!(target: "luna_orm", command = "upsert", sql = sql);
63 let args = entity.any_arguments_of_upsert();
64 let result = self.execute(&sql, args).await?;
65 debug!(target: "luna_orm", command = "upsert", result = ?result);
66 return Ok(result.rows_affected() > 0);
67 }
68
69 async fn update(
70 &mut self,
71 mutation: &dyn Mutation,
72 primary: &dyn Primary,
73 ) -> LunaOrmResult<bool> {
74 debug!(target: "luna_orm", command = "update", mutation = ?mutation, primary = ?primary);
75 let sql = self.get_generator().get_update_sql(mutation, primary);
76 debug!(target: "luna_orm", command = "update", sql = sql);
77 let mut args = mutation.any_arguments();
78 let where_args = primary.any_arguments();
79 args = luna_merge_args(args, where_args);
80 let result = self.execute(&sql, args).await?;
81 debug!(target: "luna_orm", command = "update", result = ?result);
82 return Ok(result.rows_affected() > 0);
83 }
84
85 async fn delete(&mut self, primary: &dyn Primary) -> LunaOrmResult<bool> {
86 debug!(target: "luna_orm", command = "delete", primary = ?primary);
87 let sql = self.get_generator().get_delete_sql(primary);
88 debug!(target: "luna_orm", command = "delete", sql = sql);
89 let args = primary.any_arguments();
90 let result = self.execute(&sql, args).await?;
91 debug!(target: "luna_orm", command = "delete", result = ?result);
92 return Ok(result.rows_affected() > 0);
93 }
94
95 async fn search_all<SE>(&mut self, selection: &dyn Selection) -> LunaOrmResult<Vec<SE>>
96 where
97 SE: SelectedEntity + Send + Unpin,
98 {
99 debug!(target: "luna_orm", command = "search_all", selection = ?selection);
100 let sql = self.get_generator().get_search_all_sql(selection);
101 debug!(target: "luna_orm", command = "search_all", sql = sql);
102 let result: Vec<SE> = self.fetch_all_plain(&sql).await?;
103 debug!(target: "luna_orm", command = "search_all", result = ?result);
104 return Ok(result);
105 }
106
107 async fn search<SE>(
108 &mut self,
109 location: &dyn Location,
110 order_by: Option<&dyn OrderBy>,
111 selection: &dyn Selection,
112 ) -> LunaOrmResult<Vec<SE>>
113 where
114 SE: SelectedEntity + Send + Unpin,
115 {
116 debug!(target: "luna_orm", command = "search", location = ?location, order_by = ?order_by, selection = ?selection);
117 let sql = self
118 .get_generator()
119 .get_search_sql(selection, location, order_by);
120 debug!(target: "luna_orm", command = "search", sql = sql);
121 if order_by.is_some() {
122 let order_by_fields = order_by.unwrap().get_order_by_fields();
123 let valid_order_by = location.check_valid_order_by(order_by_fields);
124 if !valid_order_by {
125 return Err(LunaOrmError::OrderByFieldsError);
126 }
127 }
128 let args = location.any_arguments();
129 let result: Vec<SE> = self.fetch_all(&sql, args).await?;
130 debug!(target: "luna_orm", command = "search", result = ?result);
131 return Ok(result);
132 }
133
134 async fn count(&mut self, location: &dyn Location) -> LunaOrmResult<usize> {
135 debug!(target: "luna_orm", command = "count", location = ?location);
136 let args = location.any_arguments();
137 let count_sql = self.get_generator().get_search_count_sql(location);
138 debug!(target: "luna_orm", command = "count", sql = count_sql);
139 let record_count: Option<RecordCount> = self.fetch_optional(&count_sql, args).await?;
140 debug!(target: "luna_orm", command = "count", result = ?record_count);
141 if record_count.is_none() {
142 return Ok(0);
143 } else {
144 return Ok(record_count.unwrap().count as usize);
145 }
146 }
147
148 async fn search_paged<SE>(
149 &mut self,
150 location: &dyn Location,
151 order_by: Option<&dyn OrderBy>,
152 selection: &dyn Selection,
153 page: &Pagination,
154 ) -> LunaOrmResult<PagedList<SE>>
155 where
156 SE: SelectedEntity + Send + Unpin,
157 {
158 debug!(target: "luna_orm", command = "search_paged", location = ?location, order_by = ?order_by, selection = ?selection, page = ?page);
159 if order_by.is_some() {
160 let order_by_fields = order_by.unwrap().get_order_by_fields();
161 let valid_order_by = location.check_valid_order_by(order_by_fields);
162 if !valid_order_by {
163 return Err(LunaOrmError::OrderByFieldsError);
164 }
165 }
166 let args = location.any_arguments();
167 let count_sql = self.get_generator().get_search_count_sql(location);
168 debug!(target: "luna_orm", command = "search_paged", count_sql = count_sql);
169 let record_count: Option<RecordCount> = self.fetch_optional(&count_sql, args).await?;
170 if record_count.is_none() {
171 return Ok(PagedList::empty(page.page_size, page.page_num));
172 }
173 let record_count: RecordCount = record_count.unwrap();
174 if record_count.count <= 0 {
175 return Ok(PagedList::empty(page.page_size, page.page_num));
176 }
177 let record_count: i64 = record_count.count;
178
179 let sql = self
180 .get_generator()
181 .get_paged_search_sql(selection, location, order_by, page);
182 debug!(target: "luna_orm", command = "search_paged", sql = sql);
183 let args = location.any_arguments();
184 let entity_list: Vec<SE> = self.fetch_all(&sql, args).await?;
185 let page_info = PageInfo {
186 page_size: page.page_size,
187 page_num: page.page_num,
188 page_total: (record_count / page.page_size as i64) as usize,
189 total: record_count as usize,
190 };
191
192 let result = PagedList {
193 data: entity_list,
194 page: page_info,
195 };
196 debug!(target: "luna_orm", command = "search_paged", result = ?result);
197 Ok(result)
198 }
199
200 async fn search_joined<SE>(
201 &mut self,
202 joined_conds: JoinedConditions,
203 locations: Vec<&dyn Location>,
204 order_by: Option<&dyn OrderBy>,
205 selections: Vec<&dyn Selection>,
206 page: &Pagination,
207 ) -> String
208{
212 self.get_generator().get_page_joined_search_sql(
213 &joined_conds,
214 &locations,
215 order_by,
216 &selections,
217 page,
218 )
219 }
220
221 async fn purify(&mut self, location: &dyn Location) -> LunaOrmResult<usize> {
222 debug!(target: "luna_orm", command = "purify", location = ?location);
223 let sql = self.get_generator().get_purify_sql(location);
224 debug!(target: "luna_orm", command = "purify", sql = sql);
225 let args = location.any_arguments();
226 let result = self.execute(&sql, args).await?;
227 debug!(target: "luna_orm", command = "purify", result = ?result);
228 return Ok(result.rows_affected() as usize);
229 }
230
231 async fn change(
232 &mut self,
233 mutation: &dyn Mutation,
234 location: &dyn Location,
235 ) -> LunaOrmResult<usize> {
236 debug!(target: "luna_orm", command = "change", mutation = ?mutation, location = ?location);
237 let sql = self.get_generator().get_change_sql(mutation, location);
238 debug!(target: "luna_orm", command = "change", sql = sql);
239 let mut args = mutation.any_arguments();
240 let where_args = location.any_arguments();
241 args = luna_merge_args(args, where_args);
242 let result = self.execute(&sql, args).await?;
243 debug!(target: "luna_orm", command = "change", result = ?result);
244 return Ok(result.rows_affected() as usize);
245 }
246
247 async fn execute_by_template(&mut self, template: &dyn TemplateRecord) -> LunaOrmResult<usize> {
248 debug!(target: "luna_orm", command = "execute_by_template", template = ?template);
249 let sql = template.get_sql(None);
250 let sql = self.get_generator().post_process(sql);
251 debug!(target: "luna_orm", command = "execute_by_template", sql = sql);
252 let args = template.any_arguments();
253 let result = self.execute(&sql, args).await?;
254 debug!(target: "luna_orm", command = "execute_by_template", result = ?result);
255 return Ok(result.rows_affected() as usize);
256 }
257
258 async fn select_by_template<SE>(
259 &mut self,
260 template: &dyn TemplateRecord,
261 ) -> LunaOrmResult<Option<SE>>
262 where
263 SE: SelectedEntity + Send + Unpin,
264 {
265 debug!(target: "luna_orm", command = "select_by_template", template = ?template);
266 let sql = template.get_sql(None);
267 let sql = self.get_generator().post_process(sql);
268 debug!(target: "luna_orm", command = "select_by_template", sql = sql);
269 let args = template.any_arguments();
270 let result: Option<SE> = self.fetch_optional(&sql, args).await?;
271 debug!(target: "luna_orm", command = "select_by_template", result = ?result);
272 return Ok(result);
273 }
274 async fn search_by_template<SE>(
275 &mut self,
276 template: &dyn TemplateRecord,
277 ) -> LunaOrmResult<Vec<SE>>
278 where
279 SE: SelectedEntity + Send + Unpin,
280 {
281 debug!(target: "luna_orm", command = "search_by_template", template = ?template);
282 let sql = template.get_sql(None);
283 let sql = self.get_generator().post_process(sql);
284 debug!(target: "luna_orm", command = "search_by_template", sql = sql);
285 let args = template.any_arguments();
286 let result: Vec<SE> = self.fetch_all(&sql, args).await?;
287 debug!(target: "luna_orm", command = "search_by_template", result = ?result);
288 return Ok(result);
289 }
290
291 async fn search_paged_by_template<SE>(
292 &mut self,
293 template: &dyn TemplateRecord,
294 page: &Pagination,
295 ) -> LunaOrmResult<PagedList<SE>>
296 where
297 SE: SelectedEntity + Send + Unpin,
298 {
299 debug!(target: "luna_orm", command = "search_paged_by_template", template = ?template, page = ?page);
300 let count_sql = template.get_count_sql();
301 let record_count: Option<RecordCount>;
302 let args = template.any_arguments();
303 match count_sql {
304 CountSql::Empty => {
305 return Err(LunaOrmError::PagedTemplateHasNoCountSql);
306 }
307 CountSql::PlainSql(sql) => {
308 let sql = self.get_generator().post_process(sql);
309 debug!(target: "luna_orm", command = "search_paged_by_template", count_sql = sql);
310 record_count = self.fetch_optional_plain(&sql).await?;
311 }
312 CountSql::VariabledSql(sql) => {
313 let sql = self.get_generator().post_process(sql);
314 debug!(target: "luna_orm", command = "search_paged_by_template", count_sql = sql);
315 record_count = self.fetch_optional(&sql, args).await?;
316 }
317 }
318 if record_count.is_none() {
319 return Ok(PagedList::empty(page.page_size, page.page_num));
320 }
321 let record_count: RecordCount = record_count.unwrap();
322 if record_count.count <= 0 {
323 return Ok(PagedList::empty(page.page_size, page.page_num));
324 }
325 let record_count: i64 = record_count.count;
326
327 let sql = template.get_sql(Some(page));
328 let sql = self.get_generator().post_process(sql);
329 debug!(target: "luna_orm", command = "search_paged_by_template", sql = sql);
330 let args = template.any_arguments();
331 let entity_list: Vec<SE> = self.fetch_all(&sql, args).await?;
332
333 let page_info = PageInfo {
334 page_size: page.page_size,
335 page_num: page.page_num,
336 page_total: (record_count / page.page_size as i64) as usize,
337 total: record_count as usize,
338 };
339 let result = PagedList {
340 data: entity_list,
341 page: page_info,
342 };
343 debug!(target: "luna_orm", command = "search_paged_by_template", result = ?result);
344 Ok(result)
345 }
346}