1use crate::{AsValue, Driver, DynQuery, Prepared, Result, Row, RowsAffected, truncate_long};
2use anyhow::anyhow;
3use std::fmt::{self, Display};
4
5#[derive(Default, Clone, Debug)]
6pub struct RawQuery(pub String);
7
8impl Display for RawQuery {
9 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10 write!(f, "{}", truncate_long!(self.0))
11 }
12}
13
14#[derive(Debug)]
16pub enum Query<D: Driver> {
17 Raw(RawQuery),
19 Prepared(D::Prepared),
21}
22
23impl<D: Driver> Query<D> {
24 pub fn raw(value: String) -> Self {
26 Query::Raw(RawQuery(value))
27 }
28 pub fn prepared(value: D::Prepared) -> Self {
30 Query::Prepared(value)
31 }
32 pub fn is_prepared(&self) -> bool {
34 matches!(self, Query::Prepared(..))
35 }
36 pub fn clear_bindings(&mut self) -> Result<&mut Self> {
38 if let Self::Prepared(prepared) = self {
39 prepared.clear_bindings()?;
40 };
41 Ok(self)
42 }
43 pub fn bind(&mut self, value: impl AsValue) -> Result<&mut Self> {
47 let Self::Prepared(prepared) = self else {
48 return Err(anyhow!("Cannot bind a raw query"));
49 };
50 prepared.bind(value)?;
51 Ok(self)
52 }
53 pub fn bind_index(&mut self, value: impl AsValue, index: u64) -> Result<&mut Self> {
57 let Self::Prepared(prepared) = self else {
58 return Err(anyhow!("Cannot bind index of a raw query"));
59 };
60 prepared.bind_index(value, index)?;
61 Ok(self)
62 }
63 pub fn into_dyn(self) -> DynQuery {
64 self.into()
65 }
66}
67
68impl<D: Driver> Default for Query<D> {
69 fn default() -> Self {
70 Self::raw(Default::default())
71 }
72}
73
74impl<D: Driver> From<&str> for Query<D> {
75 fn from(value: &str) -> Self {
76 Self::raw(value.into())
77 }
78}
79
80impl<D: Driver> From<String> for Query<D> {
81 fn from(value: String) -> Self {
82 Self::raw(value)
83 }
84}
85
86impl<D, P> From<P> for Query<D>
87where
88 D: Driver<Prepared = P>,
89 P: Prepared,
90{
91 fn from(value: P) -> Self {
92 Self::prepared(value)
93 }
94}
95
96impl<D: Driver> Display for Query<D> {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self {
99 Query::Raw(v) => v.fmt(f),
100 Query::Prepared(query) => query.fmt(f),
101 }
102 }
103}
104
105impl<D: Driver> AsMut<Query<D>> for Query<D> {
106 fn as_mut(&mut self) -> &mut Query<D> {
107 self
108 }
109}
110
111#[derive(Debug)]
113pub enum QueryResult {
114 Row(Row),
116 Affected(RowsAffected),
118}