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