tank_core/query/
dyn_query.rs1use crate::{Driver, Prepared, Query, RawQuery};
2use std::{
3 any::Any,
4 borrow::Cow,
5 fmt::{self, 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(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(RawQuery(value)) => value.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(value)) = self else {
34 unreachable!();
35 };
36 value
37 }
38 pub fn as_prepared<D: Driver>(&mut self) -> Option<&mut D::Prepared> {
39 if let Self::Prepared(prepared) = self {
40 return (&mut **prepared as &mut dyn Any).downcast_mut::<D::Prepared>();
41 }
42 None
43 }
44 pub fn as_str<'s>(&'s self) -> Cow<'s, str> {
45 match self {
46 Self::Raw(RawQuery(sql)) => Cow::Borrowed(sql),
47 Self::Prepared(v) => Cow::Owned(format!("{:?}", *v)),
48 }
49 }
50 pub fn push_str(&mut self, s: &str) {
51 self.buffer().push_str(s);
52 }
53 pub fn push(&mut self, c: char) {
54 self.buffer().push(c);
55 }
56 pub fn len(&self) -> usize {
57 match self {
58 Self::Raw(RawQuery(sql)) => sql.len(),
59 Self::Prepared(..) => 0,
60 }
61 }
62 pub fn is_empty(&self) -> bool {
63 match self {
64 Self::Raw(RawQuery(sql)) => sql.is_empty(),
65 Self::Prepared(..) => true,
66 }
67 }
68
69 pub fn into_query<D: Driver>(self, _driver: D) -> Query<D> {
70 self.into()
71 }
72}
73
74impl Default for DynQuery {
75 fn default() -> Self {
76 Self::Raw(Default::default())
77 }
78}
79
80impl Write for DynQuery {
81 fn write_char(&mut self, c: char) -> fmt::Result {
82 self.push(c);
83 Ok(())
84 }
85 fn write_str(&mut self, s: &str) -> fmt::Result {
86 self.push_str(s);
87 Ok(())
88 }
89}
90
91impl<D: Driver> From<Query<D>> for DynQuery {
92 fn from(value: Query<D>) -> Self {
93 match value {
94 Query::Raw(v) => Self::Raw(v),
95 Query::Prepared(p) => Self::Prepared(Box::new(p)),
96 }
97 }
98}
99
100impl<D: Driver> From<DynQuery> for Query<D> {
101 fn from(value: DynQuery) -> Self {
102 match value {
103 DynQuery::Raw(r) => Self::Raw(r),
104 DynQuery::Prepared(p) => match p.as_any().downcast::<D::Prepared>() {
105 Ok(p) => Query::Prepared(*p),
106 Err(..) => Query::raw(Default::default()),
107 },
108 }
109 }
110}
111
112impl From<DynQuery> for String {
113 fn from(value: DynQuery) -> Self {
114 match value {
115 DynQuery::Raw(RawQuery(value)) => value,
116 DynQuery::Prepared(value) => format!("{:?}", value),
117 }
118 }
119}