Skip to main content

rullst_orm/
raw.rs

1use crate::{Error, RullstValue};
2
3pub struct RawQueryBuilder {
4    pub sql: String,
5    pub bindings: Vec<RullstValue>,
6}
7
8impl RawQueryBuilder {
9    pub fn new(sql: impl Into<String>) -> Self {
10        Self {
11            sql: sql.into(),
12            bindings: Vec::new(),
13        }
14    }
15
16    pub fn bind<T: Into<RullstValue>>(mut self, value: T) -> Self {
17        self.bindings.push(value.into());
18        self
19    }
20
21    #[tracing::instrument(
22        name = "rullst.orm.query",
23        target = "rullst_orm",
24        skip(self),
25        fields(
26            orm.operation = "raw.select",
27            orm.binding_count = self.bindings.len()
28        )
29    )]
30    pub async fn map_to<T>(&self) -> Result<Vec<T>, Error>
31    where
32        for<'r> T: crate::_sqlx::FromRow<'r, <crate::RullstDatabase as crate::_sqlx::Database>::Row>
33            + Send
34            + Unpin,
35    {
36        if crate::schema::is_query_log_enabled() {
37            println!(
38                "[SQL Debug] {:?} | Bindings: [{} parameter(s)]",
39                self.sql,
40                self.bindings.len()
41            );
42        }
43
44        let mut query =
45            crate::_sqlx::query_as::<_, T>(crate::_sqlx::AssertSqlSafe(self.sql.as_str()));
46        for binding in &self.bindings {
47            match binding {
48                RullstValue::String(s) => {
49                    query = query.bind(s.clone());
50                }
51                RullstValue::Int(i) => {
52                    query = query.bind(*i);
53                }
54                RullstValue::Float(f) => {
55                    query = query.bind(*f);
56                }
57                RullstValue::Bool(b) => {
58                    query = query.bind(*b);
59                }
60            }
61        }
62
63        let results = crate::execute_query!(query, fetch_all, read_pool)
64            .map_err(|e| Error::DatabaseError(e.to_string()))?;
65        Ok(results)
66    }
67
68    #[tracing::instrument(
69        name = "rullst.orm.query",
70        target = "rullst_orm",
71        skip(self),
72        fields(
73            orm.operation = "raw.execute",
74            orm.binding_count = self.bindings.len()
75        )
76    )]
77    pub async fn execute(&self) -> Result<u64, Error> {
78        if crate::schema::is_query_log_enabled() {
79            println!(
80                "[SQL Debug] {:?} | Bindings: [{} parameter(s)]",
81                self.sql,
82                self.bindings.len()
83            );
84        }
85
86        let mut query = crate::_sqlx::query(crate::_sqlx::AssertSqlSafe(self.sql.as_str()));
87        for binding in &self.bindings {
88            match binding {
89                RullstValue::String(s) => {
90                    query = query.bind(s.clone());
91                }
92                RullstValue::Int(i) => {
93                    query = query.bind(*i);
94                }
95                RullstValue::Float(f) => {
96                    query = query.bind(*f);
97                }
98                RullstValue::Bool(b) => {
99                    query = query.bind(*b);
100                }
101            }
102        }
103
104        let result = crate::execute_query!(query, execute, pool)
105            .map_err(|e| Error::DatabaseError(e.to_string()))?;
106        Ok(result.rows_affected())
107    }
108}