mysql_async/conn/routines/
query.rs

1use std::marker::PhantomData;
2
3use futures_core::future::BoxFuture;
4use futures_util::FutureExt;
5use mysql_common::constants::Command;
6#[cfg(feature = "tracing")]
7use tracing::{field, span_enabled, Level};
8
9use crate::tracing_utils::TracingLevel;
10use crate::{Conn, TextProtocol};
11
12use super::Routine;
13
14/// A routine that performs `COM_QUERY`.
15#[derive(Debug, Copy, Clone)]
16pub struct QueryRoutine<'a, L: TracingLevel> {
17    data: &'a [u8],
18    _phantom: PhantomData<L>,
19}
20
21impl<'a, L: TracingLevel> QueryRoutine<'a, L> {
22    pub fn new(data: &'a [u8]) -> Self {
23        Self {
24            data,
25            _phantom: PhantomData,
26        }
27    }
28}
29
30impl<L: TracingLevel> Routine<()> for QueryRoutine<'_, L> {
31    fn call<'a>(&'a mut self, conn: &'a mut Conn) -> BoxFuture<'a, crate::Result<()>> {
32        #[cfg(feature = "tracing")]
33        let span = create_span!(
34            L::LEVEL,
35            "mysql_async::query",
36            mysql_async.connection.id = conn.id(),
37            mysql_async.query.sql = field::Empty,
38        );
39
40        #[cfg(feature = "tracing")]
41        if span_enabled!(Level::DEBUG) {
42            // The statement may contain sensitive data. Restrict to DEBUG.
43            span.record(
44                "mysql_async.query.sql",
45                String::from_utf8_lossy(self.data).as_ref(),
46            );
47        }
48
49        let fut = async move {
50            conn.write_command_data(Command::COM_QUERY, self.data)
51                .await?;
52            conn.read_result_set::<TextProtocol>(true).await?;
53            Ok(())
54        };
55
56        #[cfg(feature = "tracing")]
57        let fut = instrument_result!(fut, span);
58
59        fut.boxed()
60    }
61}