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).
56#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
7extern crate libsqlite3_sys as ffi;
89#[cfg(all(target_family = "wasm", target_os = "unknown"))]
10use sqlite_wasm_rs as ffi;
1112use super::SqliteConnection;
1314// 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_STMTas u32;
19#[allow(clippy::unnecessary_cast)]
20pub(crate) const TRACE_PROFILE: u32 = ffi::SQLITE_TRACE_PROFILEas u32;
21#[allow(clippy::unnecessary_cast)]
22pub(crate) const TRACE_ROW: u32 = ffi::SQLITE_TRACE_ROWas u32;
2324#[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" 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]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_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]
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]
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 /// SQLite's `SQLITE_TRACE_CLOSE` event is intentionally not exposed. Diesel
31 /// removes the trace callback before closing the connection, so a close
32 /// event can never reach the callback.
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
34pub struct SqliteTraceFlags: u32 {
35/// Statement start: fires when a prepared statement begins executing,
36 /// delivering the SQL text.
37const STMT = TRACE_STMT;
38/// Statement profile: fires when a statement finishes, delivering the
39 /// SQL text and the elapsed time in nanoseconds.
40const PROFILE = TRACE_PROFILE;
41/// Row: fires for every row a query returns. Very frequent and carries
42 /// no data, so prefer `STMT` and `PROFILE` for most logging.
43const ROW = TRACE_ROW;
44 }
45}4647/// Trace events delivered to the trace callback.
48///
49/// The callback receives one of these events based on the mask
50/// registered with [`on_trace`](crate::sqlite::SqliteConnection::on_trace).
51#[derive(#[automatically_derived]
impl<'a> ::core::fmt::Debug for SqliteTraceEvent<'a> {
#[inline]
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", __self_0, "readonly", &__self_1),
Self::Profile {
sql: __self_0, duration_ns: __self_1, readonly: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f,
"Profile", "sql", __self_0, "duration_ns", __self_1,
"readonly", &__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]
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)]
52#[non_exhaustive]
53pub enum SqliteTraceEvent<'a> {
54/// A prepared statement is beginning to execute.
55#[non_exhaustive]
56Statement {
57/// The unexpanded SQL text, with parameter placeholders. For triggers
58 /// and nested statements SQLite may report this as a `-- comment`
59 /// rather than the SQL itself.
60sql: &'a str,
61/// Whether the statement is read-only, via
62 /// [`sqlite3_stmt_readonly`](https://sqlite.org/c3ref/stmt_readonly.html)
63 /// (`true` for `SELECT` and read-only `PRAGMA`). Indirect writes, such
64 /// as a user-defined function on another connection or a virtual table
65 /// with side effects, are not detected.
66readonly: bool,
67 },
6869/// A prepared statement has finished executing.
70#[non_exhaustive]
71Profile {
72/// The SQL text of the statement (from `sqlite3_sql`).
73sql: &'a str,
74/// Time taken in nanoseconds.
75duration_ns: u64,
76/// Whether the statement is read-only. See
77 /// [`SqliteTraceEvent::Statement::readonly`] for details.
78readonly: bool,
79 },
8081/// A row has been returned from a query.
82 ///
83 /// Fires for every returned row and carries no data.
84#[non_exhaustive]
85Row,
86}
8788impl SqliteConnection {
89/// Registers a trace callback for SQL execution monitoring.
90 ///
91 /// The callback receives the [`SqliteTraceEvent`]s selected by the
92 /// [`SqliteTraceFlags`] mask. `ROW` fires once per returned row, so prefer
93 /// `STMT`/`PROFILE` for most logging.
94 ///
95 /// Only one trace callback can be active at a time per connection.
96 /// Registering a new one replaces the previous.
97 ///
98 /// The callback must not use the database connection. It is invoked
99 /// synchronously on the thread driving the connection, so it is never
100 /// called concurrently. Panics in the callback abort the process.
101 ///
102 /// See: [`sqlite3_trace_v2`](https://sqlite.org/c3ref/trace_v2.html)
103 ///
104 /// # Example
105 ///
106 /// ```rust
107 /// # use diesel::prelude::*;
108 /// use diesel::sqlite::{SqliteConnection, SqliteTraceFlags, SqliteTraceEvent};
109 ///
110 /// # let conn = &mut SqliteConnection::establish(":memory:").unwrap();
111 /// conn.on_trace(SqliteTraceFlags::STMT | SqliteTraceFlags::PROFILE, |event| {
112 /// match event {
113 /// SqliteTraceEvent::Statement { sql, readonly, .. } => {
114 /// println!("Executing ({}): {}", if readonly { "read" } else { "write" }, sql);
115 /// }
116 /// SqliteTraceEvent::Profile { sql, duration_ns, .. } => {
117 /// println!("{} took {} ns", sql, duration_ns);
118 /// }
119 /// _ => {}
120 /// }
121 /// });
122 ///
123 /// // Later: remove the trace callback
124 /// conn.remove_trace();
125 /// ```
126pub fn on_trace<F>(&mut self, mask: SqliteTraceFlags, hook: F)
127where
128F: FnMut(SqliteTraceEvent<'_>) + Send + 'static,
129 {
130self.raw_connection.set_trace(mask, hook);
131 }
132133/// Removes the trace callback.
134 ///
135 /// See [`on_trace`](Self::on_trace) for usage example.
136pub fn remove_trace(&mut self) {
137self.raw_connection.remove_trace();
138 }
139}
140141// miri doesn't support ffi callbacks
142#[cfg(all(test, not(miri)))]
143mod tests {
144use super::*;
145use crate::connection::Connection;
146use crate::query_dsl::RunQueryDsl;
147use std::sync::Arc;
148use std::sync::atomic::Ordering;
149150fn connection() -> SqliteConnection {
151 SqliteConnection::establish(":memory:").unwrap()
152 }
153154#[diesel_test_helper::test]
155fn on_trace_reports_statement_and_profile() {
156use std::sync::Mutex;
157158let conn = &mut connection();
159crate::sql_query("CREATE TABLE t_trace (id INTEGER PRIMARY KEY)")
160 .execute(conn)
161 .unwrap();
162163// (sql, readonly) for Statement events, and the SQL of Profile events.
164let stmts: Arc<Mutex<Vec<(String, bool)>>> = Arc::new(Mutex::new(Vec::new()));
165let profiled: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new()));
166let stmts2 = stmts.clone();
167let profiled2 = profiled.clone();
168169 conn.on_trace(
170 SqliteTraceFlags::STMT | SqliteTraceFlags::PROFILE,
171move |event| match event {
172 SqliteTraceEvent::Statement { sql, readonly } => {
173 stmts2.lock().unwrap().push((sql.to_owned(), readonly));
174 }
175 SqliteTraceEvent::Profile { sql, .. } => {
176 profiled2.lock().unwrap().push(sql.to_owned());
177 }
178_ => {}
179 },
180 );
181182crate::sql_query("SELECT id FROM t_trace")
183 .execute(conn)
184 .unwrap();
185crate::sql_query("INSERT INTO t_trace (id) VALUES (1)")
186 .execute(conn)
187 .unwrap();
188189let stmts = stmts.lock().unwrap();
190assert!(
191 stmts
192 .iter()
193 .any(|(sql, ro)| sql.contains("SELECT id FROM t_trace") && *ro),
194"the SELECT should be traced and reported read-only"
195);
196assert!(
197 stmts
198 .iter()
199 .any(|(sql, ro)| sql.contains("INSERT INTO t_trace") && !*ro),
200"the INSERT should be traced and reported not read-only"
201);
202assert!(
203 !profiled.lock().unwrap().is_empty(),
204"at least one Profile event should have fired"
205);
206 }
207208#[diesel_test_helper::test]
209fn remove_trace_stops_events() {
210use std::sync::atomic::AtomicUsize;
211212let conn = &mut connection();
213let count: Arc<AtomicUsize> = Arc::new(AtomicUsize::new(0));
214let count2 = count.clone();
215216 conn.on_trace(SqliteTraceFlags::STMT, move |_event| {
217 count2.fetch_add(1, Ordering::Relaxed);
218 });
219crate::sql_query("SELECT 1").execute(conn).unwrap();
220let after_first = count.load(Ordering::Relaxed);
221assert!(after_first > 0, "trace should fire while registered");
222223 conn.remove_trace();
224crate::sql_query("SELECT 1").execute(conn).unwrap();
225assert_eq!(
226 count.load(Ordering::Relaxed),
227 after_first,
228"no trace events should fire after remove_trace"
229);
230 }
231}