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}