planetscale_driver/
querybuilder.rs

1use crate::{structs::ExecuteResponse, Deserializer, PSConnection, Parser};
2use anyhow::Result;
3use core::fmt;
4
5pub struct QueryBuilder {
6    query: String,
7    values: Vec<String>,
8}
9
10impl QueryBuilder {
11    pub fn new(query: &str) -> Self {
12        Self {
13            query: query.to_string(),
14            values: Vec::new(),
15        }
16    }
17
18    pub fn bind<T: ToString>(mut self, value: T) -> Self {
19        let sanitized = value
20            .to_string()
21            .replace('\'', "''")
22            .replace('\"', "\\\"")
23            .replace('`', "\\`");
24
25        self.values.push(sanitized);
26        self
27    }
28
29    fn generate_query(&self) -> String {
30        let mut query = self.query.clone();
31        for i in 0..self.values.len() {
32            query = query.replace(&format!("${}", i), &self.values[i]);
33        }
34
35        query
36    }
37
38    pub async fn execute(self, connection: &PSConnection) -> Result<()> {
39        connection.execute(&self.generate_query()).await
40    }
41
42    pub async fn execute_raw(self, connection: &PSConnection) -> Result<ExecuteResponse> {
43        connection.execute_raw(&self.generate_query()).await
44    }
45
46    pub async fn fetch_one<T>(self, conn: &PSConnection) -> Result<T>
47    where
48        T: Deserializer,
49    {
50        let res = self.execute_raw(conn).await?;
51        if let Some(err) = res.error {
52            anyhow::bail!(err.message);
53        }
54
55        let res = res.deserialize()?;
56        Ok(res)
57    }
58
59    pub async fn fetch_all<T>(self, conn: &PSConnection) -> Result<Vec<T>>
60    where
61        T: Deserializer,
62    {
63        let res = self.execute_raw(conn).await?;
64        if let Some(err) = res.error {
65            anyhow::bail!(err.message);
66        }
67
68        let res = res.deserialize_multiple()?;
69        Ok(res)
70    }
71
72    pub async fn fetch_scalar<T>(self, conn: &PSConnection) -> Result<T>
73    where
74        T: Parser,
75    {
76        let res = self.execute_raw(conn).await?;
77        if let Some(err) = res.error {
78            anyhow::bail!(err.message);
79        }
80
81        let res = res.deserialize_scalar()?;
82        Ok(res)
83    }
84}
85
86impl fmt::Debug for QueryBuilder {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        write!(f, "{}", self.generate_query())
89    }
90}