luna_orm/
command_executor.rs

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//-> LunaOrmResult<PagedList<SE>>
209    //where
210    //    SE: SelectedEntity + Send + Unpin,
211    {
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}