1use crate::{AsValue, Driver, Error, Prepared, Result, Value, truncate_long};
2use std::{
3 fmt::{self, Display},
4 sync::Arc,
5};
6
7#[derive(Debug)]
9pub enum Query<D: Driver> {
10 Raw(String),
12 Prepared(D::Prepared),
14}
15
16impl<D: Driver> Query<D> {
17 pub fn is_prepared(&self) -> bool {
19 matches!(self, Query::Prepared(..))
20 }
21 pub fn clear_bindings(&mut self) -> Result<&mut Self> {
23 let Self::Prepared(prepared) = self else {
24 return Err(Error::msg("Cannot clear bindings of a raw query"));
25 };
26 prepared.clear_bindings()?;
27 Ok(self)
28 }
29 pub fn bind(&mut self, value: impl AsValue) -> Result<&mut Self> {
32 let Self::Prepared(prepared) = self else {
33 return Err(Error::msg("Cannot bind a raw query"));
34 };
35 prepared.bind(value)?;
36 Ok(self)
37 }
38 pub fn bind_index(&mut self, value: impl AsValue, index: u64) -> Result<&mut Self> {
41 let Self::Prepared(prepared) = self else {
42 return Err(Error::msg("Cannot bind index of a raw query"));
43 };
44 prepared.bind_index(value, index)?;
45 Ok(self)
46 }
47}
48
49pub trait AsQuery<D: Driver> {
50 type Output: AsMut<Query<D>> + Send;
51 fn as_query(self) -> Self::Output;
52}
53
54impl<D: Driver> AsQuery<D> for Query<D> {
55 type Output = Query<D>;
56 fn as_query(self) -> Self::Output {
57 self
58 }
59}
60
61impl<'q, D: Driver + 'q> AsQuery<D> for &'q mut Query<D> {
62 type Output = &'q mut Query<D>;
63 fn as_query(self) -> Self::Output {
64 self
65 }
66}
67
68impl<D: Driver> AsQuery<D> for String {
69 type Output = Query<D>;
70 fn as_query(self) -> Self::Output {
71 Query::Raw(self)
72 }
73}
74
75impl<D: Driver> AsQuery<D> for &str {
76 type Output = Query<D>;
77 fn as_query(self) -> Self::Output {
78 Query::Raw(self.to_owned())
79 }
80}
81
82impl<D: Driver> Default for Query<D> {
83 fn default() -> Self {
84 Self::Raw(Default::default())
85 }
86}
87
88impl<D: Driver> From<&str> for Query<D> {
89 fn from(value: &str) -> Self {
90 Query::Raw(value.into())
91 }
92}
93
94impl<D: Driver> From<String> for Query<D> {
95 fn from(value: String) -> Self {
96 Query::Raw(value.into())
97 }
98}
99
100impl<D, P> From<P> for Query<D>
101where
102 D: Driver<Prepared = P>,
103 P: Prepared,
104{
105 fn from(value: P) -> Self {
106 Query::Prepared(value)
107 }
108}
109
110impl<D: Driver> Display for Query<D> {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 match self {
113 Query::Raw(query) => write!(f, "{}", truncate_long!(query)),
114 Query::Prepared(query) => query.fmt(f),
115 }
116 }
117}
118
119impl<D: Driver> AsMut<Query<D>> for Query<D> {
120 fn as_mut(&mut self) -> &mut Query<D> {
121 self
122 }
123}
124
125#[derive(Default, Debug, Clone, Copy)]
127pub struct RowsAffected {
128 pub rows_affected: Option<u64>,
130 pub last_affected_id: Option<i64>,
132}
133
134pub type RowNames = Arc<[String]>;
136pub type Row = Box<[Value]>;
138
139#[derive(Debug, Clone)]
141pub struct RowLabeled {
142 pub labels: RowNames,
144 pub values: Row,
146}
147
148impl RowLabeled {
149 pub fn new(names: RowNames, values: Row) -> Self {
150 Self {
151 labels: names,
152 values,
153 }
154 }
155 pub fn names(&self) -> &[String] {
157 &self.labels
158 }
159 pub fn values(&self) -> &[Value] {
161 &self.values
162 }
163 pub fn get_column(&self, name: &str) -> Option<&Value> {
165 self.labels
166 .iter()
167 .position(|v| v == name)
168 .map(|i| &self.values()[i])
169 }
170}
171
172#[derive(Debug)]
174pub enum QueryResult {
175 Row(RowLabeled),
177 Affected(RowsAffected),
179}
180
181impl Extend<RowsAffected> for RowsAffected {
182 fn extend<T: IntoIterator<Item = RowsAffected>>(&mut self, iter: T) {
183 for elem in iter {
184 if self.rows_affected.is_some() || elem.rows_affected.is_some() {
185 self.rows_affected = Some(
186 self.rows_affected.unwrap_or_default() + elem.rows_affected.unwrap_or_default(),
187 );
188 }
189 if elem.last_affected_id.is_some() {
190 self.last_affected_id = elem.last_affected_id;
191 }
192 }
193 }
194}
195
196impl From<RowLabeled> for Row {
197 fn from(value: RowLabeled) -> Self {
198 value.values
199 }
200}
201
202impl<'a> From<&'a RowLabeled> for &'a Row {
203 fn from(value: &'a RowLabeled) -> Self {
204 &value.values
205 }
206}
207
208impl From<RowLabeled> for QueryResult {
209 fn from(value: RowLabeled) -> Self {
210 QueryResult::Row(value)
211 }
212}
213
214impl From<RowsAffected> for QueryResult {
215 fn from(value: RowsAffected) -> Self {
216 QueryResult::Affected(value)
217 }
218}