diesel/query_builder/
debug_query.rs
1use super::{AstPass, QueryBuilder, QueryFragment};
2use crate::backend::Backend;
3use std::fmt::{self, Debug, Display};
4use std::marker::PhantomData;
5
6pub struct DebugQuery<'a, T: 'a, DB> {
17 pub(crate) query: &'a T,
18 _marker: PhantomData<DB>,
19}
20
21impl<'a, T, DB> DebugQuery<'a, T, DB> {
22 pub(crate) fn new(query: &'a T) -> Self {
23 DebugQuery {
24 query,
25 _marker: PhantomData,
26 }
27 }
28}
29
30fn serialize_query<DB>(query: &dyn QueryFragment<DB>) -> Result<String, fmt::Error>
31where
32 DB: Backend + Default,
33 DB::QueryBuilder: Default,
34{
35 let mut query_builder = DB::QueryBuilder::default();
36 let backend = DB::default();
37 QueryFragment::<DB>::to_sql(query, &mut query_builder, &backend).map_err(|_| fmt::Error)?;
38 Ok(query_builder.finish())
39}
40
41fn display<DB>(query: &dyn QueryFragment<DB>, f: &mut fmt::Formatter<'_>) -> fmt::Result
42where
43 DB: Backend + Default,
44 DB::QueryBuilder: Default,
45{
46 let debug_binds = DebugBinds::<DB>::new(query);
47 let query = serialize_query(query)?;
48 write!(f, "{} -- binds: {:?}", query, debug_binds)
49}
50
51fn debug<DB>(query: &dyn QueryFragment<DB>, f: &mut fmt::Formatter<'_>) -> fmt::Result
52where
53 DB: Backend + Default,
54 DB::QueryBuilder: Default,
55{
56 let debug_binds = DebugBinds::<DB>::new(query);
57 let query = serialize_query(query)?;
58 f.debug_struct("Query")
59 .field("sql", &query)
60 .field("binds", &debug_binds)
61 .finish()
62}
63
64impl<T, DB> Display for DebugQuery<'_, T, DB>
65where
66 DB: Backend + Default,
67 DB::QueryBuilder: Default,
68 T: QueryFragment<DB>,
69{
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 display(self.query, f)
72 }
73}
74
75impl<T, DB> Debug for DebugQuery<'_, T, DB>
76where
77 DB: Backend + Default,
78 DB::QueryBuilder: Default,
79 T: QueryFragment<DB>,
80{
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 debug(self.query, f)
83 }
84}
85
86pub(crate) struct DebugBinds<'a, DB> {
89 query: &'a dyn QueryFragment<DB>,
90}
91
92impl<'a, DB> DebugBinds<'a, DB>
93where
94 DB: Backend,
95{
96 fn new(query: &'a dyn QueryFragment<DB>) -> Self {
97 DebugBinds { query }
98 }
99}
100
101impl<DB> Debug for DebugBinds<'_, DB>
102where
103 DB: Backend + Default,
104{
105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 let backend = DB::default();
107 let mut buffer = Vec::new();
108 let ast_pass = AstPass::debug_binds(&mut buffer, &backend);
109 self.query.walk_ast(ast_pass).map_err(|_| fmt::Error)?;
110 format_list(f, &buffer)
111 }
112}
113
114fn format_list<'b>(f: &mut fmt::Formatter<'_>, entries: &[Box<dyn Debug + 'b>]) -> fmt::Result {
115 let mut list = f.debug_list();
116 for entry in entries {
117 list.entry(entry);
118 }
119 list.finish()
120}