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