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