tank_core/query/
dyn_query.rs1use crate::{Driver, Prepared, Query, QueryParam, RawQuery};
2use std::{
3 any::Any,
4 borrow::Cow,
5 fmt::{self, Display, Write},
6};
7
8#[derive(Debug)]
10pub enum DynQuery {
11 Raw(RawQuery),
12 Prepared(Box<dyn Prepared>),
13}
14
15impl DynQuery {
16 pub fn new(value: String) -> Self {
17 Self::Raw(RawQuery::new(value))
18 }
19 pub fn with_capacity(capacity: usize) -> Self {
20 Self::new(String::with_capacity(capacity))
21 }
22 pub fn clear(&mut self) {
23 match self {
24 Self::Raw(raw) => raw.clear(),
25 Self::Prepared(..) => *self = Self::Raw(Default::default()),
26 }
27 }
28 pub fn buffer(&mut self) -> &mut String {
29 if !matches!(self, Self::Raw(..)) {
30 log::error!("DynQuery::buffer changed the query to raw, deleting the previous content");
31 *self = Self::Raw(Default::default())
32 }
33 let Self::Raw(RawQuery { sql, .. }) = self else {
34 unreachable!();
35 };
36 sql
37 }
38 pub fn mark_param(&mut self, param: QueryParam) {
40 if let Self::Raw(RawQuery { params, .. }) = self {
41 params.push(param);
42 }
43 }
44 pub fn as_prepared<D: Driver>(&mut self) -> Option<&mut D::Prepared> {
45 if let Self::Prepared(prepared) = self {
46 return (&mut **prepared as &mut dyn Any).downcast_mut::<D::Prepared>();
47 }
48 None
49 }
50 pub fn as_str<'s>(&'s self) -> Cow<'s, str> {
51 match self {
52 Self::Raw(RawQuery { sql, .. }) => Cow::Borrowed(sql),
53 Self::Prepared(v) => Cow::Owned(format!("{:?}", *v)),
54 }
55 }
56 pub fn push_str(&mut self, s: &str) {
57 self.buffer().push_str(s);
58 }
59 pub fn push(&mut self, c: char) {
60 self.buffer().push(c);
61 }
62 pub fn len(&self) -> usize {
63 match self {
64 Self::Raw(RawQuery { sql, .. }) => sql.len(),
65 Self::Prepared(..) => 0,
66 }
67 }
68 pub fn is_empty(&self) -> bool {
69 match self {
70 Self::Raw(RawQuery { sql, .. }) => sql.is_empty(),
71 Self::Prepared(..) => true,
72 }
73 }
74
75 pub fn into_query<D: Driver>(self, _driver: D) -> Query<D> {
76 self.into()
77 }
78}
79
80impl Default for DynQuery {
81 fn default() -> Self {
82 Self::Raw(Default::default())
83 }
84}
85
86impl Write for DynQuery {
87 fn write_char(&mut self, c: char) -> fmt::Result {
88 self.push(c);
89 Ok(())
90 }
91 fn write_str(&mut self, s: &str) -> fmt::Result {
92 self.push_str(s);
93 Ok(())
94 }
95}
96
97impl<D: Driver> From<Query<D>> for DynQuery {
98 fn from(value: Query<D>) -> Self {
99 match value {
100 Query::Raw(v) => Self::Raw(v),
101 Query::Prepared(p) => Self::Prepared(Box::new(p)),
102 }
103 }
104}
105
106impl<D: Driver> From<DynQuery> for Query<D> {
107 fn from(value: DynQuery) -> Self {
108 match value {
109 DynQuery::Raw(r) => Self::Raw(r),
110 DynQuery::Prepared(p) => match p.as_any().downcast::<D::Prepared>() {
111 Ok(p) => Query::Prepared(*p),
112 Err(..) => Query::raw(Default::default()),
113 },
114 }
115 }
116}
117
118impl From<DynQuery> for String {
119 fn from(value: DynQuery) -> Self {
120 match value {
121 DynQuery::Raw(RawQuery { sql, .. }) => sql,
122 DynQuery::Prepared(value) => format!("{:?}", value),
123 }
124 }
125}
126
127impl Display for DynQuery {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 match self {
130 DynQuery::Raw(v) => v.fmt(f),
131 DynQuery::Prepared(v) => v.fmt(f),
132 }
133 }
134}