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