Skip to main content

diesel/sqlite/connection/
trace.rs

1//! Types for the SQLite trace callback.
2//!
3//! See [`sqlite3_trace_v2`](https://sqlite.org/c3ref/trace_v2.html)
4//! and the [trace event codes](https://sqlite.org/c3ref/c_trace.html).
5
6#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
7extern crate libsqlite3_sys as ffi;
8
9#[cfg(all(target_family = "wasm", target_os = "unknown"))]
10use sqlite_wasm_rs as ffi;
11
12use super::SqliteConnection;
13
14// The `SQLITE_TRACE_*` constants are typed `i32` in old `libsqlite3-sys` and
15// `c_uint` in new ones. Normalize them to `u32` here, the single place these
16// constants are read. The casts are required for the old versions.
17#[allow(clippy::unnecessary_cast)]
18pub(crate) const TRACE_STMT: u32 = ffi::SQLITE_TRACE_STMT as u32;
19#[allow(clippy::unnecessary_cast)]
20pub(crate) const TRACE_PROFILE: u32 = ffi::SQLITE_TRACE_PROFILE as u32;
21#[allow(clippy::unnecessary_cast)]
22pub(crate) const TRACE_ROW: u32 = ffi::SQLITE_TRACE_ROW as u32;
23
24#[doc = r" Trace event mask selecting which events the callback receives."]
#[doc = r""]
#[doc = r" Added in SQLite 3.14.0 (2016-08-08). Combine flags with `|`, and"]
#[doc = r" `SqliteTraceFlags::all()` selects every event."]
#[doc = r""]
#[doc =
r" Bits that are not one of the declared flags, for example set through"]
#[doc =
r" `from_bits_retain`, are discarded before the callback is registered."]
#[doc = r""]
#[doc =
r" SQLite's `SQLITE_TRACE_CLOSE` event is intentionally not exposed. Diesel"]
#[doc =
r" removes the trace callback before closing the connection, so a close"]
#[doc = r" event can never reach the callback."]
pub struct SqliteTraceFlags(<SqliteTraceFlags as
    ::bitflags::__private::PublicFlags>::Internal);
#[automatically_derived]impl ::core::fmt::Debug for SqliteTraceFlags {
    #[inline]
    #[rustc_trivial_field_reads]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f,
            "SqliteTraceFlags", &&self.0)
    }
}
#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for SqliteTraceFlags {
}
#[automatically_derived]impl ::core::clone::Clone for SqliteTraceFlags {
    #[inline]
    #[rustc_trivial_field_reads]
    fn clone(&self) -> Self {
        let _:
                ::core::clone::AssertParamIsClone<<SqliteTraceFlags as
                ::bitflags::__private::PublicFlags>::Internal>;
        *self
    }
}
#[automatically_derived]impl ::core::marker::Copy for SqliteTraceFlags { }
#[automatically_derived]impl ::core::marker::StructuralPartialEq for
    SqliteTraceFlags {
}
#[automatically_derived]impl ::core::cmp::PartialEq for SqliteTraceFlags {
    #[inline]
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
#[automatically_derived]impl ::core::cmp::Eq for SqliteTraceFlags {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _:
                ::core::cmp::AssertParamIsEq<<SqliteTraceFlags as
                ::bitflags::__private::PublicFlags>::Internal>;
    }
}
#[automatically_derived]impl ::core::hash::Hash for SqliteTraceFlags {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}
#[allow(dead_code, deprecated, unused_doc_comments, unused_attributes,
unused_mut, unused_imports, non_upper_case_globals, clippy :: min_ident_chars,
clippy :: assign_op_pattern, clippy :: indexing_slicing, clippy ::
same_name_method, clippy :: iter_without_into_iter,)]
impl SqliteTraceFlags {
    #[doc =
    r" Statement start: fires when a prepared statement begins executing,"]
    #[doc = r" delivering the SQL text."]
    pub const STMT: Self = Self::from_bits_retain(TRACE_STMT);
    #[doc =
    r" Statement profile: fires when a statement finishes, delivering the"]
    #[doc = r" SQL text and the elapsed time in nanoseconds."]
    pub const PROFILE: Self = Self::from_bits_retain(TRACE_PROFILE);
    #[doc =
    r" Row: fires for every row a query returns. Very frequent and carries"]
    #[doc = r" no data, so prefer `STMT` and `PROFILE` for most logging."]
    pub const ROW: Self = Self::from_bits_retain(TRACE_ROW);
}
#[allow(dead_code, deprecated, unused_doc_comments, unused_attributes,
unused_mut, unused_imports, non_upper_case_globals, clippy :: min_ident_chars,
clippy :: assign_op_pattern, clippy :: indexing_slicing, clippy ::
same_name_method, clippy :: iter_without_into_iter,)]
impl ::bitflags::Flags for SqliteTraceFlags {
    const FLAGS: &'static [::bitflags::Flag<SqliteTraceFlags>] =
        {
            mod __bitflags_flag_names {
                #[allow(unused_imports)]
                use super::*;
                pub(super) const STMT: &'static str = "STMT";
                pub(super) const PROFILE: &'static str = "PROFILE";
                pub(super) const ROW: &'static str = "ROW";
            }
            &[{
                            ::bitflags::Flag::new(__bitflags_flag_names::STMT,
                                SqliteTraceFlags::STMT)
                        },
                        {
                            ::bitflags::Flag::new(__bitflags_flag_names::PROFILE,
                                SqliteTraceFlags::PROFILE)
                        },
                        {
                            ::bitflags::Flag::new(__bitflags_flag_names::ROW,
                                SqliteTraceFlags::ROW)
                        }]
        };
    type Bits = u32;
    fn bits(&self) -> u32 { SqliteTraceFlags::bits(self) }
    fn from_bits_retain(bits: u32) -> SqliteTraceFlags {
        SqliteTraceFlags::from_bits_retain(bits)
    }
    fn all_named() -> SqliteTraceFlags {
        const ALL_NAMED: u32 =
            {
                let mut truncated = <u32 as ::bitflags::Bits>::EMPTY;
                let mut i = 0;
                {
                    {
                        let flag =
                            &<SqliteTraceFlags as ::bitflags::Flags>::FLAGS[i];
                        if flag.is_named() {
                            truncated = truncated | flag.value().bits();
                        }
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            &<SqliteTraceFlags as ::bitflags::Flags>::FLAGS[i];
                        if flag.is_named() {
                            truncated = truncated | flag.value().bits();
                        }
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            &<SqliteTraceFlags as ::bitflags::Flags>::FLAGS[i];
                        if flag.is_named() {
                            truncated = truncated | flag.value().bits();
                        }
                        i += 1;
                    }
                };
                let _ = i;
                truncated
            };
        SqliteTraceFlags::from_bits_retain(ALL_NAMED)
    }
}
#[allow(dead_code, deprecated, unused_doc_comments, unused_attributes,
unused_mut, unused_imports, non_upper_case_globals, clippy :: min_ident_chars,
clippy :: assign_op_pattern, clippy :: indexing_slicing, clippy ::
same_name_method, clippy :: iter_without_into_iter,)]
const _: () =
    {
        #[repr(transparent)]
        pub struct InternalBitFlags(u32);
        #[automatically_derived]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone for InternalBitFlags { }
        #[automatically_derived]
        impl ::core::clone::Clone for InternalBitFlags {
            #[inline]
            #[rustc_trivial_field_reads]
            fn clone(&self) -> Self {
                let _: ::core::clone::AssertParamIsClone<u32>;
                *self
            }
        }
        #[automatically_derived]
        impl ::core::marker::Copy for InternalBitFlags { }
        #[automatically_derived]
        impl ::core::marker::StructuralPartialEq for InternalBitFlags { }
        #[automatically_derived]
        impl ::core::cmp::PartialEq for InternalBitFlags {
            #[inline]
            fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
        }
        #[automatically_derived]
        impl ::core::cmp::Eq for InternalBitFlags {
            #[inline]
            #[doc(hidden)]
            #[coverage(off)]
            fn assert_fields_are_eq(&self) {
                let _: ::core::cmp::AssertParamIsEq<u32>;
            }
        }
        #[automatically_derived]
        impl ::core::cmp::PartialOrd for InternalBitFlags {
            #[inline]
            fn partial_cmp(&self, other: &Self)
                -> ::core::option::Option<::core::cmp::Ordering> {
                ::core::option::Option::Some(::core::cmp::Ord::cmp(self,
                        other))
            }
        }
        #[automatically_derived]
        impl ::core::cmp::Ord for InternalBitFlags {
            #[inline]
            fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
                ::core::cmp::Ord::cmp(&self.0, &other.0)
            }
        }
        #[automatically_derived]
        impl ::core::hash::Hash for InternalBitFlags {
            #[inline]
            fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
                ::core::hash::Hash::hash(&self.0, state)
            }
        }
        impl ::bitflags::__private::PublicFlags for SqliteTraceFlags {
            type Primitive = u32;
            type Internal = InternalBitFlags;
        }
        impl ::bitflags::__private::core::default::Default for
            InternalBitFlags {
            #[inline]
            fn default() -> Self { InternalBitFlags::empty() }
        }
        impl ::bitflags::__private::core::fmt::Debug for InternalBitFlags {
            fn fmt(&self,
                f: &mut ::bitflags::__private::core::fmt::Formatter<'_>)
                -> ::bitflags::__private::core::fmt::Result {
                if self.is_empty() {
                    f.write_fmt(format_args!("{0:#x}",
                            <u32 as ::bitflags::Bits>::EMPTY))
                } else {
                    ::bitflags::__private::core::fmt::Display::fmt(self, f)
                }
            }
        }
        impl ::bitflags::__private::core::fmt::Display for InternalBitFlags {
            fn fmt(&self,
                f: &mut ::bitflags::__private::core::fmt::Formatter<'_>)
                -> ::bitflags::__private::core::fmt::Result {
                ::bitflags::parser::to_writer(&SqliteTraceFlags(*self), f)
            }
        }
        impl ::bitflags::__private::core::str::FromStr for InternalBitFlags {
            type Err = ::bitflags::parser::ParseError;
            fn from_str(s: &str)
                ->
                    ::bitflags::__private::core::result::Result<Self,
                    Self::Err> {
                ::bitflags::parser::from_str::<SqliteTraceFlags>(s).map(|flags|
                        flags.0)
            }
        }
        impl ::bitflags::__private::core::convert::AsRef<u32> for
            InternalBitFlags {
            fn as_ref(&self) -> &u32 { &self.0 }
        }
        impl ::bitflags::__private::core::convert::From<u32> for
            InternalBitFlags {
            fn from(bits: u32) -> Self { Self::from_bits_retain(bits) }
        }
        impl InternalBitFlags {
            /// Get a flags value with all bits unset.
            #[inline]
            pub const fn empty() -> Self {
                Self(<u32 as ::bitflags::Bits>::EMPTY)
            }
            /// Get a flags value with all known bits set.
            #[inline]
            pub const fn all() -> Self {
                const ALL: InternalBitFlags =
                    {
                        let mut truncated = <u32 as ::bitflags::Bits>::EMPTY;
                        let mut _i = 0;
                        {
                            {
                                truncated |=
                                    <SqliteTraceFlags as
                                                    ::bitflags::Flags>::FLAGS[_i].value().bits();
                                _i += 1;
                            }
                        };
                        {
                            {
                                truncated |=
                                    <SqliteTraceFlags as
                                                    ::bitflags::Flags>::FLAGS[_i].value().bits();
                                _i += 1;
                            }
                        };
                        {
                            {
                                truncated |=
                                    <SqliteTraceFlags as
                                                    ::bitflags::Flags>::FLAGS[_i].value().bits();
                                _i += 1;
                            }
                        };
                        InternalBitFlags(truncated)
                    };
                ALL
            }
            /// Get the underlying bits value.
            ///
            /// The returned value is exactly the bits set in this flags value.
            #[inline]
            pub const fn bits(&self) -> u32 { self.0 }
            /// Convert from a bits value.
            ///
            /// This method will return `None` if any unknown bits are set.
            #[inline]
            pub const fn from_bits(bits: u32)
                -> ::bitflags::__private::core::option::Option<Self> {
                let truncated = Self::from_bits_truncate(bits).0;
                if truncated == bits {
                    ::bitflags::__private::core::option::Option::Some(Self(bits))
                } else { ::bitflags::__private::core::option::Option::None }
            }
            /// Convert from a bits value, unsetting any unknown bits.
            #[inline]
            pub const fn from_bits_truncate(bits: u32) -> Self {
                Self(bits & Self::all().0)
            }
            /// Convert from a bits value exactly.
            #[inline]
            pub const fn from_bits_retain(bits: u32) -> Self { Self(bits) }
            /// Get a flags value with the bits of a flag with the given name set.
            ///
            /// This method will return `None` if `name` is empty or doesn't
            /// correspond to any named flag.
            #[inline]
            pub fn from_name(name: &str)
                -> ::bitflags::__private::core::option::Option<Self> {
                mod __bitflags_flag_names {
                    #[allow(unused_imports)]
                    use super::*;
                    pub(super) const STMT: &'static str = "STMT";
                    pub(super) const PROFILE: &'static str = "PROFILE";
                    pub(super) const ROW: &'static str = "ROW";
                }
                {
                    {
                        if name == __bitflags_flag_names::STMT {
                            return ::bitflags::__private::core::option::Option::Some(Self(SqliteTraceFlags::STMT.bits()));
                        }
                    };
                };
                {
                    {
                        if name == __bitflags_flag_names::PROFILE {
                            return ::bitflags::__private::core::option::Option::Some(Self(SqliteTraceFlags::PROFILE.bits()));
                        }
                    };
                };
                {
                    {
                        if name == __bitflags_flag_names::ROW {
                            return ::bitflags::__private::core::option::Option::Some(Self(SqliteTraceFlags::ROW.bits()));
                        }
                    };
                };
                let _ = name;
                ::bitflags::__private::core::option::Option::None
            }
            /// Whether all bits in `self` are unset.
            #[inline]
            pub const fn is_empty(&self) -> bool {
                self.0 == <u32 as ::bitflags::Bits>::EMPTY
            }
            /// Whether all known bits in this flags value are set.
            #[inline]
            pub const fn is_all(&self) -> bool {
                Self::all().0 | self.0 == self.0
            }
            /// Whether any set bits in `other` are also set in `self`.
            #[inline]
            pub const fn intersects(&self, other: Self) -> bool {
                self.0 & other.0 != <u32 as ::bitflags::Bits>::EMPTY
            }
            /// Whether all set bits in `other` are also set in `self`.
            #[inline]
            pub const fn contains(&self, other: Self) -> bool {
                self.0 & other.0 == other.0
            }
            /// The bitwise or (`|`) of the bits in `self` and `other`.
            #[inline]
            pub fn insert(&mut self, other: Self) {
                *self = Self(self.0).union(other);
            }
            /// The intersection of `self` with the complement of `other` (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `remove` won't truncate `other`, but the `!` operator will.
            #[inline]
            pub fn remove(&mut self, other: Self) {
                *self = Self(self.0).difference(other);
            }
            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
            #[inline]
            pub fn toggle(&mut self, other: Self) {
                *self = Self(self.0).symmetric_difference(other);
            }
            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
            #[inline]
            pub fn set(&mut self, other: Self, value: bool) {
                if value { self.insert(other); } else { self.remove(other); }
            }
            /// The bitwise and (`&`) of the bits in `self` and `other`.
            #[inline]
            #[must_use]
            pub const fn intersection(self, other: Self) -> Self {
                Self(self.0 & other.0)
            }
            /// The bitwise or (`|`) of the bits in `self` and `other`.
            #[inline]
            #[must_use]
            pub const fn union(self, other: Self) -> Self {
                Self(self.0 | other.0)
            }
            /// The intersection of `self` with the complement of `other` (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            #[must_use]
            pub const fn difference(self, other: Self) -> Self {
                Self(self.0 & !other.0)
            }
            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
            #[inline]
            #[must_use]
            pub const fn symmetric_difference(self, other: Self) -> Self {
                Self(self.0 ^ other.0)
            }
            /// The bitwise negation (`!`) of the bits in `self`, truncating the result.
            #[inline]
            #[must_use]
            pub const fn complement(self) -> Self {
                Self::from_bits_truncate(!self.0)
            }
        }
        impl ::bitflags::__private::core::fmt::Binary for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Binary::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::Octal for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Octal::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::LowerHex for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::LowerHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::UpperHex for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::UpperHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::ops::BitOr for InternalBitFlags {
            type Output = Self;
            /// The bitwise or (`|`) of the bits in `self` and `other`.
            #[inline]
            fn bitor(self, other: InternalBitFlags) -> Self {
                self.union(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitOrAssign for
            InternalBitFlags {
            /// The bitwise or (`|`) of the bits in `self` and `other`.
            #[inline]
            fn bitor_assign(&mut self, other: Self) { self.insert(other); }
        }
        impl ::bitflags::__private::core::ops::BitXor for InternalBitFlags {
            type Output = Self;
            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
            #[inline]
            fn bitxor(self, other: Self) -> Self {
                self.symmetric_difference(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitXorAssign for
            InternalBitFlags {
            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
            #[inline]
            fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
        }
        impl ::bitflags::__private::core::ops::BitAnd for InternalBitFlags {
            type Output = Self;
            /// The bitwise and (`&`) of the bits in `self` and `other`.
            #[inline]
            fn bitand(self, other: Self) -> Self { self.intersection(other) }
        }
        impl ::bitflags::__private::core::ops::BitAndAssign for
            InternalBitFlags {
            /// The bitwise and (`&`) of the bits in `self` and `other`.
            #[inline]
            fn bitand_assign(&mut self, other: Self) {
                *self =
                    Self::from_bits_retain(self.bits()).intersection(other);
            }
        }
        impl ::bitflags::__private::core::ops::Sub for InternalBitFlags {
            type Output = Self;
            /// The intersection of `self` with the complement of `other` (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub(self, other: Self) -> Self { self.difference(other) }
        }
        impl ::bitflags::__private::core::ops::SubAssign for InternalBitFlags
            {
            /// The intersection of `self` with the complement of `other` (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub_assign(&mut self, other: Self) { self.remove(other); }
        }
        impl ::bitflags::__private::core::ops::Not for InternalBitFlags {
            type Output = Self;
            /// The bitwise negation (`!`) of the bits in `self`, truncating the result.
            #[inline]
            fn not(self) -> Self { self.complement() }
        }
        impl ::bitflags::__private::core::iter::Extend<InternalBitFlags> for
            InternalBitFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn extend<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(&mut self, iterator: T) {
                for item in iterator { self.insert(item) }
            }
        }
        impl ::bitflags::__private::core::iter::FromIterator<InternalBitFlags>
            for InternalBitFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn from_iter<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(iterator: T) -> Self {
                use ::bitflags::__private::core::iter::Extend;
                let mut result = Self::empty();
                result.extend(iterator);
                result
            }
        }
        impl InternalBitFlags {
            /// Yield a set of contained flags values.
            ///
            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
            /// will be yielded together as a final flags value.
            #[inline]
            pub const fn iter(&self)
                -> ::bitflags::iter::Iter<SqliteTraceFlags> {
                ::bitflags::iter::Iter::__private_const_new(<SqliteTraceFlags
                        as ::bitflags::Flags>::FLAGS,
                    SqliteTraceFlags::from_bits_retain(self.bits()),
                    SqliteTraceFlags::from_bits_retain(self.bits()))
            }
            /// Yield a set of contained named flags values.
            ///
            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
            #[inline]
            pub const fn iter_names(&self)
                -> ::bitflags::iter::IterNames<SqliteTraceFlags> {
                ::bitflags::iter::IterNames::__private_const_new(<SqliteTraceFlags
                        as ::bitflags::Flags>::FLAGS,
                    SqliteTraceFlags::from_bits_retain(self.bits()),
                    SqliteTraceFlags::from_bits_retain(self.bits()))
            }
        }
        impl ::bitflags::__private::core::iter::IntoIterator for
            InternalBitFlags {
            type Item = SqliteTraceFlags;
            type IntoIter = ::bitflags::iter::Iter<SqliteTraceFlags>;
            fn into_iter(self) -> Self::IntoIter { self.iter() }
        }
        impl InternalBitFlags {
            /// Returns a mutable reference to the raw value of the flags currently stored.
            #[inline]
            pub fn bits_mut(&mut self) -> &mut u32 { &mut self.0 }
        }
        impl SqliteTraceFlags {
            /// Get a flags value with all bits unset.
            #[inline]
            pub const fn empty() -> Self { Self(InternalBitFlags::empty()) }
            /// Get a flags value with all known bits set.
            #[inline]
            pub const fn all() -> Self { Self(InternalBitFlags::all()) }
            /// Get the underlying bits value.
            ///
            /// The returned value is exactly the bits set in this flags value.
            #[inline]
            pub const fn bits(&self) -> u32 { self.0.bits() }
            /// Convert from a bits value.
            ///
            /// This method will return `None` if any unknown bits are set.
            #[inline]
            pub const fn from_bits(bits: u32)
                -> ::bitflags::__private::core::option::Option<Self> {
                match InternalBitFlags::from_bits(bits) {
                    ::bitflags::__private::core::option::Option::Some(bits) =>
                        ::bitflags::__private::core::option::Option::Some(Self(bits)),
                    ::bitflags::__private::core::option::Option::None =>
                        ::bitflags::__private::core::option::Option::None,
                }
            }
            /// Convert from a bits value, unsetting any unknown bits.
            #[inline]
            pub const fn from_bits_truncate(bits: u32) -> Self {
                Self(InternalBitFlags::from_bits_truncate(bits))
            }
            /// Convert from a bits value exactly.
            #[inline]
            pub const fn from_bits_retain(bits: u32) -> Self {
                Self(InternalBitFlags::from_bits_retain(bits))
            }
            /// Get a flags value with the bits of a flag with the given name set.
            ///
            /// This method will return `None` if `name` is empty or doesn't
            /// correspond to any named flag.
            #[inline]
            pub fn from_name(name: &str)
                -> ::bitflags::__private::core::option::Option<Self> {
                match InternalBitFlags::from_name(name) {
                    ::bitflags::__private::core::option::Option::Some(bits) =>
                        ::bitflags::__private::core::option::Option::Some(Self(bits)),
                    ::bitflags::__private::core::option::Option::None =>
                        ::bitflags::__private::core::option::Option::None,
                }
            }
            /// Whether all bits in `self` are unset.
            #[inline]
            pub const fn is_empty(&self) -> bool { self.0.is_empty() }
            /// Whether all known bits in this flags value are set.
            #[inline]
            pub const fn is_all(&self) -> bool { self.0.is_all() }
            /// Whether any set bits in `other` are also set in `self`.
            #[inline]
            pub const fn intersects(&self, other: Self) -> bool {
                self.0.intersects(other.0)
            }
            /// Whether all set bits in `other` are also set in `self`.
            #[inline]
            pub const fn contains(&self, other: Self) -> bool {
                self.0.contains(other.0)
            }
            /// The bitwise or (`|`) of the bits in `self` and `other`.
            #[inline]
            pub fn insert(&mut self, other: Self) { self.0.insert(other.0) }
            /// The intersection of `self` with the complement of `other` (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `remove` won't truncate `other`, but the `!` operator will.
            #[inline]
            pub fn remove(&mut self, other: Self) { self.0.remove(other.0) }
            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
            #[inline]
            pub fn toggle(&mut self, other: Self) { self.0.toggle(other.0) }
            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
            #[inline]
            pub fn set(&mut self, other: Self, value: bool) {
                self.0.set(other.0, value)
            }
            /// The bitwise and (`&`) of the bits in `self` and `other`.
            #[inline]
            #[must_use]
            pub const fn intersection(self, other: Self) -> Self {
                Self(self.0.intersection(other.0))
            }
            /// The bitwise or (`|`) of the bits in `self` and `other`.
            #[inline]
            #[must_use]
            pub const fn union(self, other: Self) -> Self {
                Self(self.0.union(other.0))
            }
            /// The intersection of `self` with the complement of `other` (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            #[must_use]
            pub const fn difference(self, other: Self) -> Self {
                Self(self.0.difference(other.0))
            }
            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
            #[inline]
            #[must_use]
            pub const fn symmetric_difference(self, other: Self) -> Self {
                Self(self.0.symmetric_difference(other.0))
            }
            /// The bitwise negation (`!`) of the bits in `self`, truncating the result.
            #[inline]
            #[must_use]
            pub const fn complement(self) -> Self {
                Self(self.0.complement())
            }
        }
        impl ::bitflags::__private::core::fmt::Binary for SqliteTraceFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Binary::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::Octal for SqliteTraceFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Octal::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::LowerHex for SqliteTraceFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::LowerHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::UpperHex for SqliteTraceFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::UpperHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::ops::BitOr for SqliteTraceFlags {
            type Output = Self;
            /// The bitwise or (`|`) of the bits in `self` and `other`.
            #[inline]
            fn bitor(self, other: SqliteTraceFlags) -> Self {
                self.union(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitOrAssign for
            SqliteTraceFlags {
            /// The bitwise or (`|`) of the bits in `self` and `other`.
            #[inline]
            fn bitor_assign(&mut self, other: Self) { self.insert(other); }
        }
        impl ::bitflags::__private::core::ops::BitXor for SqliteTraceFlags {
            type Output = Self;
            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
            #[inline]
            fn bitxor(self, other: Self) -> Self {
                self.symmetric_difference(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitXorAssign for
            SqliteTraceFlags {
            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
            #[inline]
            fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
        }
        impl ::bitflags::__private::core::ops::BitAnd for SqliteTraceFlags {
            type Output = Self;
            /// The bitwise and (`&`) of the bits in `self` and `other`.
            #[inline]
            fn bitand(self, other: Self) -> Self { self.intersection(other) }
        }
        impl ::bitflags::__private::core::ops::BitAndAssign for
            SqliteTraceFlags {
            /// The bitwise and (`&`) of the bits in `self` and `other`.
            #[inline]
            fn bitand_assign(&mut self, other: Self) {
                *self =
                    Self::from_bits_retain(self.bits()).intersection(other);
            }
        }
        impl ::bitflags::__private::core::ops::Sub for SqliteTraceFlags {
            type Output = Self;
            /// The intersection of `self` with the complement of `other` (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub(self, other: Self) -> Self { self.difference(other) }
        }
        impl ::bitflags::__private::core::ops::SubAssign for SqliteTraceFlags
            {
            /// The intersection of `self` with the complement of `other` (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub_assign(&mut self, other: Self) { self.remove(other); }
        }
        impl ::bitflags::__private::core::ops::Not for SqliteTraceFlags {
            type Output = Self;
            /// The bitwise negation (`!`) of the bits in `self`, truncating the result.
            #[inline]
            fn not(self) -> Self { self.complement() }
        }
        impl ::bitflags::__private::core::iter::Extend<SqliteTraceFlags> for
            SqliteTraceFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn extend<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(&mut self, iterator: T) {
                for item in iterator { self.insert(item) }
            }
        }
        impl ::bitflags::__private::core::iter::FromIterator<SqliteTraceFlags>
            for SqliteTraceFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn from_iter<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(iterator: T) -> Self {
                use ::bitflags::__private::core::iter::Extend;
                let mut result = Self::empty();
                result.extend(iterator);
                result
            }
        }
        impl SqliteTraceFlags {
            /// Yield a set of contained flags values.
            ///
            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
            /// will be yielded together as a final flags value.
            #[inline]
            pub const fn iter(&self)
                -> ::bitflags::iter::Iter<SqliteTraceFlags> {
                ::bitflags::iter::Iter::__private_const_new(<SqliteTraceFlags
                        as ::bitflags::Flags>::FLAGS,
                    SqliteTraceFlags::from_bits_retain(self.bits()),
                    SqliteTraceFlags::from_bits_retain(self.bits()))
            }
            /// Yield a set of contained named flags values.
            ///
            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
            #[inline]
            pub const fn iter_names(&self)
                -> ::bitflags::iter::IterNames<SqliteTraceFlags> {
                ::bitflags::iter::IterNames::__private_const_new(<SqliteTraceFlags
                        as ::bitflags::Flags>::FLAGS,
                    SqliteTraceFlags::from_bits_retain(self.bits()),
                    SqliteTraceFlags::from_bits_retain(self.bits()))
            }
        }
        impl ::bitflags::__private::core::iter::IntoIterator for
            SqliteTraceFlags {
            type Item = SqliteTraceFlags;
            type IntoIter = ::bitflags::iter::Iter<SqliteTraceFlags>;
            fn into_iter(self) -> Self::IntoIter { self.iter() }
        }
    };bitflags::bitflags! {
25    /// Trace event mask selecting which events the callback receives.
26    ///
27    /// Added in SQLite 3.14.0 (2016-08-08). Combine flags with `|`, and
28    /// `SqliteTraceFlags::all()` selects every event.
29    ///
30    /// Bits that are not one of the declared flags, for example set through
31    /// `from_bits_retain`, are discarded before the callback is registered.
32    ///
33    /// SQLite's `SQLITE_TRACE_CLOSE` event is intentionally not exposed. Diesel
34    /// removes the trace callback before closing the connection, so a close
35    /// event can never reach the callback.
36    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
37    pub struct SqliteTraceFlags: u32 {
38        /// Statement start: fires when a prepared statement begins executing,
39        /// delivering the SQL text.
40        const STMT = TRACE_STMT;
41        /// Statement profile: fires when a statement finishes, delivering the
42        /// SQL text and the elapsed time in nanoseconds.
43        const PROFILE = TRACE_PROFILE;
44        /// Row: fires for every row a query returns. Very frequent and carries
45        /// no data, so prefer `STMT` and `PROFILE` for most logging.
46        const ROW = TRACE_ROW;
47    }
48}
49
50/// Trace events delivered to the trace callback.
51///
52/// The callback receives one of these events based on the mask
53/// registered with [`on_trace`](crate::sqlite::SqliteConnection::on_trace).
54#[derive(#[automatically_derived]impl<'a> ::core::fmt::Debug for SqliteTraceEvent<'a> {
    #[inline]
    #[rustc_trivial_field_reads]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Statement { sql: __self_0, readonly: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Statement sql readonly", __self_0, &__self_1),
            Self::Profile {
                sql: __self_0, duration_ns: __self_1, readonly: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "Profile sql duration_ns readonly", __self_0, __self_1,
                    &__self_2),
            Self::Row => ::core::fmt::Formatter::write_str(f, "Row"),
        }
    }
}Debug, #[automatically_derived]#[doc(hidden)]unsafe impl<'a>
    ::core::clone::TrivialClone for SqliteTraceEvent<'a> {
}
#[automatically_derived]impl<'a> ::core::clone::Clone for SqliteTraceEvent<'a>
    {
    #[inline]
    #[rustc_trivial_field_reads]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<&'a str>;
        let _: ::core::clone::AssertParamIsClone<bool>;
        let _: ::core::clone::AssertParamIsClone<&'a str>;
        let _: ::core::clone::AssertParamIsClone<u64>;
        *self
    }
}Clone, #[automatically_derived]impl<'a> ::core::marker::Copy for SqliteTraceEvent<'a>
    {
}Copy)]
55#[non_exhaustive]
56pub enum SqliteTraceEvent<'a> {
57    /// A prepared statement is beginning to execute.
58    #[non_exhaustive]
59    Statement {
60        /// The unexpanded SQL text, with parameter placeholders. For triggers
61        /// and nested statements SQLite may report this as a `-- comment`
62        /// rather than the SQL itself.
63        sql: &'a str,
64        /// Whether the statement is read-only, via
65        /// [`sqlite3_stmt_readonly`](https://sqlite.org/c3ref/stmt_readonly.html)
66        /// (`true` for `SELECT` and read-only `PRAGMA`). Indirect writes, such
67        /// as a user-defined function on another connection or a virtual table
68        /// with side effects, are not detected.
69        readonly: bool,
70    },
71
72    /// A prepared statement has finished executing.
73    #[non_exhaustive]
74    Profile {
75        /// The SQL text of the statement (from `sqlite3_sql`).
76        sql: &'a str,
77        /// Time taken in nanoseconds.
78        duration_ns: u64,
79        /// Whether the statement is read-only. See
80        /// [`SqliteTraceEvent::Statement::readonly`] for details.
81        readonly: bool,
82    },
83
84    /// A row has been returned from a query.
85    ///
86    /// Fires for every returned row and carries no data.
87    #[non_exhaustive]
88    Row,
89}
90
91impl SqliteConnection {
92    /// Registers a trace callback for SQL execution monitoring.
93    ///
94    /// The callback receives the [`SqliteTraceEvent`]s selected by the
95    /// [`SqliteTraceFlags`] mask. `ROW` fires once per returned row, so prefer
96    /// `STMT`/`PROFILE` for most logging.
97    ///
98    /// Only one trace callback can be active at a time per connection.
99    /// Registering a new one replaces the previous.
100    ///
101    /// The callback must not use the database connection. It is invoked
102    /// synchronously on the thread driving the connection, so it is never
103    /// called concurrently. Panics in the callback abort the process.
104    ///
105    /// See: [`sqlite3_trace_v2`](https://sqlite.org/c3ref/trace_v2.html)
106    ///
107    /// # Example
108    ///
109    /// ```rust
110    /// # use diesel::prelude::*;
111    /// use diesel::sqlite::{SqliteConnection, SqliteTraceFlags, SqliteTraceEvent};
112    ///
113    /// # let conn = &mut SqliteConnection::establish(":memory:").unwrap();
114    /// conn.on_trace(SqliteTraceFlags::STMT | SqliteTraceFlags::PROFILE, |event| {
115    ///     match event {
116    ///         SqliteTraceEvent::Statement { sql, readonly, .. } => {
117    ///             println!("Executing ({}): {}", if readonly { "read" } else { "write" }, sql);
118    ///         }
119    ///         SqliteTraceEvent::Profile { sql, duration_ns, .. } => {
120    ///             println!("{} took {} ns", sql, duration_ns);
121    ///         }
122    ///         _ => {}
123    ///     }
124    /// });
125    ///
126    /// // Later: remove the trace callback
127    /// conn.remove_trace();
128    /// ```
129    pub fn on_trace<F>(&mut self, mask: SqliteTraceFlags, hook: F)
130    where
131        F: FnMut(SqliteTraceEvent<'_>) + Send + 'static,
132    {
133        self.raw_connection.set_trace(mask, hook);
134    }
135
136    /// Removes the trace callback.
137    ///
138    /// See [`on_trace`](Self::on_trace) for usage example.
139    pub fn remove_trace(&mut self) {
140        self.raw_connection.remove_trace();
141    }
142}
143
144// miri doesn't support ffi callbacks
145#[cfg(all(test, not(miri)))]
146mod tests {
147    use super::*;
148    use crate::connection::Connection;
149    use crate::query_dsl::RunQueryDsl;
150    use std::sync::Arc;
151    use std::sync::atomic::Ordering;
152
153    fn connection() -> SqliteConnection {
154        SqliteConnection::establish(":memory:").unwrap()
155    }
156
157    #[diesel_test_helper::test]
158    fn on_trace_reports_statement_and_profile() {
159        use std::sync::Mutex;
160
161        let conn = &mut connection();
162        crate::sql_query("CREATE TABLE t_trace (id INTEGER PRIMARY KEY)")
163            .execute(conn)
164            .unwrap();
165
166        // (sql, readonly) for Statement events, and the SQL of Profile events.
167        let stmts: Arc<Mutex<Vec<(String, bool)>>> = Arc::new(Mutex::new(Vec::new()));
168        let profiled: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new()));
169        let stmts2 = stmts.clone();
170        let profiled2 = profiled.clone();
171
172        conn.on_trace(
173            SqliteTraceFlags::STMT | SqliteTraceFlags::PROFILE,
174            move |event| match event {
175                SqliteTraceEvent::Statement { sql, readonly } => {
176                    stmts2.lock().unwrap().push((sql.to_owned(), readonly));
177                }
178                SqliteTraceEvent::Profile { sql, .. } => {
179                    profiled2.lock().unwrap().push(sql.to_owned());
180                }
181                _ => {}
182            },
183        );
184
185        crate::sql_query("SELECT id FROM t_trace")
186            .execute(conn)
187            .unwrap();
188        crate::sql_query("INSERT INTO t_trace (id) VALUES (1)")
189            .execute(conn)
190            .unwrap();
191
192        let stmts = stmts.lock().unwrap();
193        assert!(
194            stmts
195                .iter()
196                .any(|(sql, ro)| sql.contains("SELECT id FROM t_trace") && *ro),
197            "the SELECT should be traced and reported read-only"
198        );
199        assert!(
200            stmts
201                .iter()
202                .any(|(sql, ro)| sql.contains("INSERT INTO t_trace") && !*ro),
203            "the INSERT should be traced and reported not read-only"
204        );
205        assert!(
206            !profiled.lock().unwrap().is_empty(),
207            "at least one Profile event should have fired"
208        );
209    }
210
211    #[diesel_test_helper::test]
212    fn remove_trace_stops_events() {
213        use std::sync::atomic::AtomicUsize;
214
215        let conn = &mut connection();
216        let count: Arc<AtomicUsize> = Arc::new(AtomicUsize::new(0));
217        let count2 = count.clone();
218
219        conn.on_trace(SqliteTraceFlags::STMT, move |_event| {
220            count2.fetch_add(1, Ordering::Relaxed);
221        });
222        crate::sql_query("SELECT 1").execute(conn).unwrap();
223        let after_first = count.load(Ordering::Relaxed);
224        assert!(after_first > 0, "trace should fire while registered");
225
226        conn.remove_trace();
227        crate::sql_query("SELECT 1").execute(conn).unwrap();
228        assert_eq!(
229            count.load(Ordering::Relaxed),
230            after_first,
231            "no trace events should fire after remove_trace"
232        );
233    }
234
235    #[diesel_test_helper::test]
236    fn on_trace_ignores_unknown_mask_bits() {
237        use std::sync::Mutex;
238
239        let conn = &mut connection();
240        let seen: Arc<Mutex<Vec<String>>> = Default::default();
241        let seen2 = seen.clone();
242
243        // 0x41 keeps the STMT bit plus a bit that is not a declared event code.
244        conn.on_trace(SqliteTraceFlags::from_bits_retain(0x41), move |event| {
245            if let SqliteTraceEvent::Statement { sql, .. } = event {
246                seen2.lock().unwrap().push(sql.to_string());
247            }
248        });
249        crate::sql_query("SELECT 1").execute(conn).unwrap();
250
251        assert!(
252            seen.lock().unwrap().iter().any(|sql| sql == "SELECT 1"),
253            "the SELECT should be traced despite the unknown mask bit"
254        );
255    }
256
257    #[diesel_test_helper::test]
258    fn on_trace_with_unknown_mask_bits_keeps_v2_callback() {
259        let conn = &mut connection();
260
261        // A non-capturing closure, like the one in the `on_trace` documentation.
262        conn.on_trace(SqliteTraceFlags::from_bits_retain(0x41), |_event| {});
263        crate::sql_query("SELECT 1").execute(conn).unwrap();
264    }
265}