1use crate::{AsValue, Driver, DynQuery, Prepared, Result, Row, RowsAffected, truncate_long};
2use anyhow::anyhow;
3use std::fmt::{self, Display};
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub struct QueryParam {
8 pub begin: usize,
9 pub end: usize, }
11
12#[derive(Default, Clone, Debug)]
13pub struct RawQuery {
14 pub sql: String,
15 pub params: Vec<QueryParam>,
16}
17
18impl RawQuery {
19 pub fn new(sql: String) -> Self {
20 Self {
21 sql,
22 params: Vec::new(),
23 }
24 }
25 pub fn with_params(sql: String, params: Vec<QueryParam>) -> Self {
26 Self { sql, params }
27 }
28 pub fn clear(&mut self) {
29 self.sql.clear();
30 self.params.clear();
31 }
32}
33
34impl From<String> for RawQuery {
35 fn from(value: String) -> Self {
36 Self::new(value)
37 }
38}
39
40impl From<RawQuery> for String {
41 fn from(value: RawQuery) -> Self {
42 value.sql
43 }
44}
45
46impl Display for RawQuery {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 write!(f, "{}", truncate_long!(self.sql))
49 }
50}
51
52#[derive(Debug)]
54pub enum Query<D: Driver> {
55 Raw(RawQuery),
57 Prepared(D::Prepared),
59}
60
61impl<D: Driver> Query<D> {
62 pub fn raw(value: String) -> Self {
64 Query::Raw(value.into())
65 }
66 pub fn prepared(value: D::Prepared) -> Self {
68 Query::Prepared(value)
69 }
70 pub fn is_prepared(&self) -> bool {
72 matches!(self, Query::Prepared(..))
73 }
74 pub fn clear_bindings(&mut self) -> Result<&mut Self> {
76 if let Self::Prepared(prepared) = self {
77 prepared.clear_bindings()?;
78 };
79 Ok(self)
80 }
81 pub fn bind(&mut self, value: impl AsValue) -> Result<&mut Self> {
85 let Self::Prepared(prepared) = self else {
86 return Err(anyhow!("Cannot bind a raw query"));
87 };
88 prepared.bind(value)?;
89 Ok(self)
90 }
91 pub fn bind_index(&mut self, value: impl AsValue, index: u64) -> Result<&mut Self> {
95 let Self::Prepared(prepared) = self else {
96 return Err(anyhow!("Cannot bind index of a raw query"));
97 };
98 prepared.bind_index(value, index)?;
99 Ok(self)
100 }
101 pub fn into_dyn(self) -> DynQuery {
102 self.into()
103 }
104}
105
106impl<D: Driver> Default for Query<D> {
107 fn default() -> Self {
108 Self::raw(Default::default())
109 }
110}
111
112impl<D: Driver> From<&str> for Query<D> {
113 fn from(value: &str) -> Self {
114 Self::raw(value.into())
115 }
116}
117
118impl<D: Driver> From<String> for Query<D> {
119 fn from(value: String) -> Self {
120 Self::raw(value)
121 }
122}
123
124impl<D, P> From<P> for Query<D>
125where
126 D: Driver<Prepared = P>,
127 P: Prepared,
128{
129 fn from(value: P) -> Self {
130 Self::prepared(value)
131 }
132}
133
134impl<D: Driver> Display for Query<D> {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 match self {
137 Query::Raw(v) => v.fmt(f),
138 Query::Prepared(query) => query.fmt(f),
139 }
140 }
141}
142
143impl<D: Driver> AsMut<Query<D>> for Query<D> {
144 fn as_mut(&mut self) -> &mut Query<D> {
145 self
146 }
147}
148
149#[derive(Debug)]
151pub enum QueryResult {
152 Row(Row),
154 Affected(RowsAffected),
156}