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