1#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
6extern crate libsqlite3_sys as ffi;
7
8#[cfg(all(target_family = "wasm", target_os = "unknown"))]
9use sqlite_wasm_rs as ffi;
10
11use crate::query_source::NamedTable;
12use alloc::boxed::Box;
13use alloc::vec::Vec;
14
15#[doc =
r" A bitmask of SQLite change operations used for filtering which events"]
#[doc = r" a hook should receive."]
#[doc = r""]
#[doc = r" Combine masks with `|` (bitwise OR):"]
#[doc = r""]
#[doc = r" ```rust"]
#[doc = r" # use diesel::sqlite::SqliteChangeOps;"]
#[doc =
r" let insert_or_delete = SqliteChangeOps::INSERT | SqliteChangeOps::DELETE;"]
#[doc = r" assert!(insert_or_delete.contains(SqliteChangeOps::INSERT));"]
#[doc = r" assert!(!insert_or_delete.contains(SqliteChangeOps::UPDATE));"]
#[doc = r" ```"]
pub struct SqliteChangeOps(<SqliteChangeOps as
::bitflags::__private::PublicFlags>::Internal);
#[automatically_derived]
impl ::core::fmt::Debug for SqliteChangeOps {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"SqliteChangeOps", &&self.0)
}
}
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for SqliteChangeOps { }
#[automatically_derived]
impl ::core::clone::Clone for SqliteChangeOps {
#[inline]
fn clone(&self) -> SqliteChangeOps {
let _:
::core::clone::AssertParamIsClone<<SqliteChangeOps as
::bitflags::__private::PublicFlags>::Internal>;
*self
}
}
#[automatically_derived]
impl ::core::marker::Copy for SqliteChangeOps { }
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for SqliteChangeOps { }
#[automatically_derived]
impl ::core::cmp::PartialEq for SqliteChangeOps {
#[inline]
fn eq(&self, other: &SqliteChangeOps) -> bool { self.0 == other.0 }
}
#[automatically_derived]
impl ::core::cmp::Eq for SqliteChangeOps {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _:
::core::cmp::AssertParamIsEq<<SqliteChangeOps as
::bitflags::__private::PublicFlags>::Internal>;
}
}
#[automatically_derived]
impl ::core::hash::Hash for SqliteChangeOps {
#[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,)]
const _: () =
{
#[repr(transparent)]
pub struct InternalBitFlags(u8);
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for InternalBitFlags { }
#[automatically_derived]
impl ::core::clone::Clone for InternalBitFlags {
#[inline]
fn clone(&self) -> InternalBitFlags {
let _: ::core::clone::AssertParamIsClone<u8>;
*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: &InternalBitFlags) -> 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<u8>;
}
}
#[automatically_derived]
impl ::core::cmp::PartialOrd for InternalBitFlags {
#[inline]
fn partial_cmp(&self, other: &InternalBitFlags)
-> ::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: &InternalBitFlags) -> ::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 SqliteChangeOps {
#[doc = r" Match INSERT operations."]
pub const INSERT: Self = Self::from_bits_retain(1);
#[doc = r" Match UPDATE operations."]
pub const UPDATE: Self = Self::from_bits_retain(2);
#[doc = r" Match DELETE operations."]
pub const DELETE: Self = Self::from_bits_retain(4);
#[doc = r" Match unknown or future operation codes."]
pub const UNKNOWN: Self = Self::from_bits_retain(8);
#[doc =
r" Match all row-change operations (INSERT, UPDATE, DELETE, and UNKNOWN)."]
#[doc = r""]
#[doc =
r" `UNKNOWN` is included deliberately: if a future SQLite version emits"]
#[doc =
r" an operation code diesel does not recognize, a hook registered with"]
#[doc =
r" `ALL` still fires (with [`SqliteChangeOp::Unknown`] carrying the raw"]
#[doc = r" code) rather than silently dropping the change."]
pub const ALL: Self =
Self::from_bits_retain(Self::INSERT.bits() |
Self::UPDATE.bits() | Self::DELETE.bits() |
Self::UNKNOWN.bits());
}
impl ::bitflags::Flags for SqliteChangeOps {
const FLAGS: &'static [::bitflags::Flag<SqliteChangeOps>] =
{
mod __bitflags_flag_names {
use super::*;
pub(super) const INSERT: &'static str = "INSERT";
pub(super) const UPDATE: &'static str = "UPDATE";
pub(super) const DELETE: &'static str = "DELETE";
pub(super) const UNKNOWN: &'static str = "UNKNOWN";
pub(super) const ALL: &'static str = "ALL";
}
&[{
::bitflags::Flag::new(__bitflags_flag_names::INSERT,
SqliteChangeOps::INSERT)
},
{
::bitflags::Flag::new(__bitflags_flag_names::UPDATE,
SqliteChangeOps::UPDATE)
},
{
::bitflags::Flag::new(__bitflags_flag_names::DELETE,
SqliteChangeOps::DELETE)
},
{
::bitflags::Flag::new(__bitflags_flag_names::UNKNOWN,
SqliteChangeOps::UNKNOWN)
},
{
::bitflags::Flag::new(__bitflags_flag_names::ALL,
SqliteChangeOps::ALL)
}]
};
type Bits = u8;
fn bits(&self) -> u8 { SqliteChangeOps::bits(self) }
fn from_bits_retain(bits: u8) -> SqliteChangeOps {
SqliteChangeOps::from_bits_retain(bits)
}
fn all_named() -> SqliteChangeOps {
const ALL_NAMED: u8 =
{
let mut truncated = <u8 as ::bitflags::Bits>::EMPTY;
let mut i = 0;
{
{
let flag =
&<SqliteChangeOps as ::bitflags::Flags>::FLAGS[i];
if flag.is_named() {
truncated = truncated | flag.value().bits();
}
i += 1;
}
};
{
{
let flag =
&<SqliteChangeOps as ::bitflags::Flags>::FLAGS[i];
if flag.is_named() {
truncated = truncated | flag.value().bits();
}
i += 1;
}
};
{
{
let flag =
&<SqliteChangeOps as ::bitflags::Flags>::FLAGS[i];
if flag.is_named() {
truncated = truncated | flag.value().bits();
}
i += 1;
}
};
{
{
let flag =
&<SqliteChangeOps as ::bitflags::Flags>::FLAGS[i];
if flag.is_named() {
truncated = truncated | flag.value().bits();
}
i += 1;
}
};
{
{
let flag =
&<SqliteChangeOps as ::bitflags::Flags>::FLAGS[i];
if flag.is_named() {
truncated = truncated | flag.value().bits();
}
i += 1;
}
};
let _ = i;
truncated
};
SqliteChangeOps::from_bits_retain(ALL_NAMED)
}
}
impl ::bitflags::__private::PublicFlags for SqliteChangeOps {
type Primitive = u8;
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}",
<u8 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(&SqliteChangeOps(*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::<SqliteChangeOps>(s).map(|flags|
flags.0)
}
}
impl ::bitflags::__private::core::convert::AsRef<u8> for
InternalBitFlags {
fn as_ref(&self) -> &u8 { &self.0 }
}
impl ::bitflags::__private::core::convert::From<u8> for
InternalBitFlags {
fn from(bits: u8) -> Self { Self::from_bits_retain(bits) }
}
impl InternalBitFlags {
#[inline]
pub const fn empty() -> Self {
Self(<u8 as ::bitflags::Bits>::EMPTY)
}
#[inline]
pub const fn all() -> Self {
const ALL: InternalBitFlags =
{
let mut truncated = <u8 as ::bitflags::Bits>::EMPTY;
let mut _i = 0;
{
{
truncated |=
<SqliteChangeOps as
::bitflags::Flags>::FLAGS[_i].value().bits();
_i += 1;
}
};
{
{
truncated |=
<SqliteChangeOps as
::bitflags::Flags>::FLAGS[_i].value().bits();
_i += 1;
}
};
{
{
truncated |=
<SqliteChangeOps as
::bitflags::Flags>::FLAGS[_i].value().bits();
_i += 1;
}
};
{
{
truncated |=
<SqliteChangeOps as
::bitflags::Flags>::FLAGS[_i].value().bits();
_i += 1;
}
};
{
{
truncated |=
<SqliteChangeOps as
::bitflags::Flags>::FLAGS[_i].value().bits();
_i += 1;
}
};
InternalBitFlags(truncated)
};
ALL
}
#[inline]
pub const fn bits(&self) -> u8 { self.0 }
#[inline]
pub const fn from_bits(bits: u8)
-> ::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 }
}
#[inline]
pub const fn from_bits_truncate(bits: u8) -> Self {
Self(bits & Self::all().0)
}
#[inline]
pub const fn from_bits_retain(bits: u8) -> Self { Self(bits) }
#[inline]
pub fn from_name(name: &str)
-> ::bitflags::__private::core::option::Option<Self> {
mod __bitflags_flag_names {
use super::*;
pub(super) const INSERT: &'static str = "INSERT";
pub(super) const UPDATE: &'static str = "UPDATE";
pub(super) const DELETE: &'static str = "DELETE";
pub(super) const UNKNOWN: &'static str = "UNKNOWN";
pub(super) const ALL: &'static str = "ALL";
}
{
{
if name == __bitflags_flag_names::INSERT {
return ::bitflags::__private::core::option::Option::Some(Self(SqliteChangeOps::INSERT.bits()));
}
};
};
{
{
if name == __bitflags_flag_names::UPDATE {
return ::bitflags::__private::core::option::Option::Some(Self(SqliteChangeOps::UPDATE.bits()));
}
};
};
{
{
if name == __bitflags_flag_names::DELETE {
return ::bitflags::__private::core::option::Option::Some(Self(SqliteChangeOps::DELETE.bits()));
}
};
};
{
{
if name == __bitflags_flag_names::UNKNOWN {
return ::bitflags::__private::core::option::Option::Some(Self(SqliteChangeOps::UNKNOWN.bits()));
}
};
};
{
{
if name == __bitflags_flag_names::ALL {
return ::bitflags::__private::core::option::Option::Some(Self(SqliteChangeOps::ALL.bits()));
}
};
};
let _ = name;
::bitflags::__private::core::option::Option::None
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.0 == <u8 as ::bitflags::Bits>::EMPTY
}
#[inline]
pub const fn is_all(&self) -> bool {
Self::all().0 | self.0 == self.0
}
#[inline]
pub const fn intersects(&self, other: Self) -> bool {
self.0 & other.0 != <u8 as ::bitflags::Bits>::EMPTY
}
#[inline]
pub const fn contains(&self, other: Self) -> bool {
self.0 & other.0 == other.0
}
#[inline]
pub fn insert(&mut self, other: Self) {
*self = Self(self.0).union(other);
}
#[inline]
pub fn remove(&mut self, other: Self) {
*self = Self(self.0).difference(other);
}
#[inline]
pub fn toggle(&mut self, other: Self) {
*self = Self(self.0).symmetric_difference(other);
}
#[inline]
pub fn set(&mut self, other: Self, value: bool) {
if value { self.insert(other); } else { self.remove(other); }
}
#[inline]
#[must_use]
pub const fn intersection(self, other: Self) -> Self {
Self(self.0 & other.0)
}
#[inline]
#[must_use]
pub const fn union(self, other: Self) -> Self {
Self(self.0 | other.0)
}
#[inline]
#[must_use]
pub const fn difference(self, other: Self) -> Self {
Self(self.0 & !other.0)
}
#[inline]
#[must_use]
pub const fn symmetric_difference(self, other: Self) -> Self {
Self(self.0 ^ other.0)
}
#[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;
#[inline]
fn bitor(self, other: InternalBitFlags) -> Self {
self.union(other)
}
}
impl ::bitflags::__private::core::ops::BitOrAssign for
InternalBitFlags {
#[inline]
fn bitor_assign(&mut self, other: Self) { self.insert(other); }
}
impl ::bitflags::__private::core::ops::BitXor for InternalBitFlags {
type Output = Self;
#[inline]
fn bitxor(self, other: Self) -> Self {
self.symmetric_difference(other)
}
}
impl ::bitflags::__private::core::ops::BitXorAssign for
InternalBitFlags {
#[inline]
fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
}
impl ::bitflags::__private::core::ops::BitAnd for InternalBitFlags {
type Output = Self;
#[inline]
fn bitand(self, other: Self) -> Self { self.intersection(other) }
}
impl ::bitflags::__private::core::ops::BitAndAssign for
InternalBitFlags {
#[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;
#[inline]
fn sub(self, other: Self) -> Self { self.difference(other) }
}
impl ::bitflags::__private::core::ops::SubAssign for InternalBitFlags
{
#[inline]
fn sub_assign(&mut self, other: Self) { self.remove(other); }
}
impl ::bitflags::__private::core::ops::Not for InternalBitFlags {
type Output = Self;
#[inline]
fn not(self) -> Self { self.complement() }
}
impl ::bitflags::__private::core::iter::Extend<InternalBitFlags> for
InternalBitFlags {
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 {
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 {
#[inline]
pub const fn iter(&self)
-> ::bitflags::iter::Iter<SqliteChangeOps> {
::bitflags::iter::Iter::__private_const_new(<SqliteChangeOps
as ::bitflags::Flags>::FLAGS,
SqliteChangeOps::from_bits_retain(self.bits()),
SqliteChangeOps::from_bits_retain(self.bits()))
}
#[inline]
pub const fn iter_names(&self)
-> ::bitflags::iter::IterNames<SqliteChangeOps> {
::bitflags::iter::IterNames::__private_const_new(<SqliteChangeOps
as ::bitflags::Flags>::FLAGS,
SqliteChangeOps::from_bits_retain(self.bits()),
SqliteChangeOps::from_bits_retain(self.bits()))
}
}
impl ::bitflags::__private::core::iter::IntoIterator for
InternalBitFlags {
type Item = SqliteChangeOps;
type IntoIter = ::bitflags::iter::Iter<SqliteChangeOps>;
fn into_iter(self) -> Self::IntoIter { self.iter() }
}
impl InternalBitFlags {
#[inline]
pub fn bits_mut(&mut self) -> &mut u8 { &mut self.0 }
}
impl SqliteChangeOps {
#[inline]
pub const fn empty() -> Self { Self(InternalBitFlags::empty()) }
#[inline]
pub const fn all() -> Self { Self(InternalBitFlags::all()) }
#[inline]
pub const fn bits(&self) -> u8 { self.0.bits() }
#[inline]
pub const fn from_bits(bits: u8)
-> ::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,
}
}
#[inline]
pub const fn from_bits_truncate(bits: u8) -> Self {
Self(InternalBitFlags::from_bits_truncate(bits))
}
#[inline]
pub const fn from_bits_retain(bits: u8) -> Self {
Self(InternalBitFlags::from_bits_retain(bits))
}
#[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,
}
}
#[inline]
pub const fn is_empty(&self) -> bool { self.0.is_empty() }
#[inline]
pub const fn is_all(&self) -> bool { self.0.is_all() }
#[inline]
pub const fn intersects(&self, other: Self) -> bool {
self.0.intersects(other.0)
}
#[inline]
pub const fn contains(&self, other: Self) -> bool {
self.0.contains(other.0)
}
#[inline]
pub fn insert(&mut self, other: Self) { self.0.insert(other.0) }
#[inline]
pub fn remove(&mut self, other: Self) { self.0.remove(other.0) }
#[inline]
pub fn toggle(&mut self, other: Self) { self.0.toggle(other.0) }
#[inline]
pub fn set(&mut self, other: Self, value: bool) {
self.0.set(other.0, value)
}
#[inline]
#[must_use]
pub const fn intersection(self, other: Self) -> Self {
Self(self.0.intersection(other.0))
}
#[inline]
#[must_use]
pub const fn union(self, other: Self) -> Self {
Self(self.0.union(other.0))
}
#[inline]
#[must_use]
pub const fn difference(self, other: Self) -> Self {
Self(self.0.difference(other.0))
}
#[inline]
#[must_use]
pub const fn symmetric_difference(self, other: Self) -> Self {
Self(self.0.symmetric_difference(other.0))
}
#[inline]
#[must_use]
pub const fn complement(self) -> Self {
Self(self.0.complement())
}
}
impl ::bitflags::__private::core::fmt::Binary for SqliteChangeOps {
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 SqliteChangeOps {
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 SqliteChangeOps {
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 SqliteChangeOps {
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 SqliteChangeOps {
type Output = Self;
#[inline]
fn bitor(self, other: SqliteChangeOps) -> Self {
self.union(other)
}
}
impl ::bitflags::__private::core::ops::BitOrAssign for SqliteChangeOps
{
#[inline]
fn bitor_assign(&mut self, other: Self) { self.insert(other); }
}
impl ::bitflags::__private::core::ops::BitXor for SqliteChangeOps {
type Output = Self;
#[inline]
fn bitxor(self, other: Self) -> Self {
self.symmetric_difference(other)
}
}
impl ::bitflags::__private::core::ops::BitXorAssign for
SqliteChangeOps {
#[inline]
fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
}
impl ::bitflags::__private::core::ops::BitAnd for SqliteChangeOps {
type Output = Self;
#[inline]
fn bitand(self, other: Self) -> Self { self.intersection(other) }
}
impl ::bitflags::__private::core::ops::BitAndAssign for
SqliteChangeOps {
#[inline]
fn bitand_assign(&mut self, other: Self) {
*self =
Self::from_bits_retain(self.bits()).intersection(other);
}
}
impl ::bitflags::__private::core::ops::Sub for SqliteChangeOps {
type Output = Self;
#[inline]
fn sub(self, other: Self) -> Self { self.difference(other) }
}
impl ::bitflags::__private::core::ops::SubAssign for SqliteChangeOps {
#[inline]
fn sub_assign(&mut self, other: Self) { self.remove(other); }
}
impl ::bitflags::__private::core::ops::Not for SqliteChangeOps {
type Output = Self;
#[inline]
fn not(self) -> Self { self.complement() }
}
impl ::bitflags::__private::core::iter::Extend<SqliteChangeOps> for
SqliteChangeOps {
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<SqliteChangeOps>
for SqliteChangeOps {
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 SqliteChangeOps {
#[inline]
pub const fn iter(&self)
-> ::bitflags::iter::Iter<SqliteChangeOps> {
::bitflags::iter::Iter::__private_const_new(<SqliteChangeOps
as ::bitflags::Flags>::FLAGS,
SqliteChangeOps::from_bits_retain(self.bits()),
SqliteChangeOps::from_bits_retain(self.bits()))
}
#[inline]
pub const fn iter_names(&self)
-> ::bitflags::iter::IterNames<SqliteChangeOps> {
::bitflags::iter::IterNames::__private_const_new(<SqliteChangeOps
as ::bitflags::Flags>::FLAGS,
SqliteChangeOps::from_bits_retain(self.bits()),
SqliteChangeOps::from_bits_retain(self.bits()))
}
}
impl ::bitflags::__private::core::iter::IntoIterator for
SqliteChangeOps {
type Item = SqliteChangeOps;
type IntoIter = ::bitflags::iter::Iter<SqliteChangeOps>;
fn into_iter(self) -> Self::IntoIter { self.iter() }
}
};bitflags::bitflags! {
16 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28 pub struct SqliteChangeOps: u8 {
29 const INSERT = 1;
31 const UPDATE = 2;
33 const DELETE = 4;
35 const UNKNOWN = 8;
37 const ALL =
44 Self::INSERT.bits() | Self::UPDATE.bits() | Self::DELETE.bits() | Self::UNKNOWN.bits();
45 }
46}
47
48impl SqliteChangeOps {
49 pub(crate) fn matches_op(self, op: SqliteChangeOp) -> bool {
51 self.contains(op.to_ops())
52 }
53}
54
55#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SqliteChangeOp {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
SqliteChangeOp::Insert =>
::core::fmt::Formatter::write_str(f, "Insert"),
SqliteChangeOp::Update =>
::core::fmt::Formatter::write_str(f, "Update"),
SqliteChangeOp::Delete =>
::core::fmt::Formatter::write_str(f, "Delete"),
SqliteChangeOp::Unknown(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Unknown", &__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SqliteChangeOp {
#[inline]
fn clone(&self) -> SqliteChangeOp {
let _: ::core::clone::AssertParamIsClone<i32>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SqliteChangeOp { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for SqliteChangeOp {
#[inline]
fn eq(&self, other: &SqliteChangeOp) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(SqliteChangeOp::Unknown(__self_0),
SqliteChangeOp::Unknown(__arg1_0)) => __self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SqliteChangeOp {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<i32>;
}
}Eq)]
60#[non_exhaustive]
61pub enum SqliteChangeOp {
62 Insert,
64 Update,
66 Delete,
68 Unknown(i32),
71}
72
73impl SqliteChangeOp {
74 pub(crate) fn from_ffi(code: i32) -> Self {
76 #[allow(non_upper_case_globals)]
77 match code {
78 ffi::SQLITE_INSERT => SqliteChangeOp::Insert,
79 ffi::SQLITE_UPDATE => SqliteChangeOp::Update,
80 ffi::SQLITE_DELETE => SqliteChangeOp::Delete,
81 other => SqliteChangeOp::Unknown(other),
82 }
83 }
84
85 pub(crate) fn to_ops(self) -> SqliteChangeOps {
88 match self {
89 SqliteChangeOp::Insert => SqliteChangeOps::INSERT,
90 SqliteChangeOp::Update => SqliteChangeOps::UPDATE,
91 SqliteChangeOp::Delete => SqliteChangeOps::DELETE,
92 SqliteChangeOp::Unknown(_) => SqliteChangeOps::UNKNOWN,
93 }
94 }
95}
96
97#[derive(#[automatically_derived]
impl<'a> ::core::fmt::Debug for SqliteChangeEvent<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f,
"SqliteChangeEvent", "op", &self.op, "db_name", &self.db_name,
"table_name", &self.table_name, "rowid", &&self.rowid)
}
}Debug, #[automatically_derived]
impl<'a> ::core::clone::Clone for SqliteChangeEvent<'a> {
#[inline]
fn clone(&self) -> SqliteChangeEvent<'a> {
let _: ::core::clone::AssertParamIsClone<SqliteChangeOp>;
let _: ::core::clone::AssertParamIsClone<&'a str>;
let _: ::core::clone::AssertParamIsClone<&'a str>;
let _: ::core::clone::AssertParamIsClone<i64>;
*self
}
}Clone, #[automatically_derived]
impl<'a> ::core::marker::Copy for SqliteChangeEvent<'a> { }Copy)]
101#[non_exhaustive]
102pub struct SqliteChangeEvent<'a> {
103 pub op: SqliteChangeOp,
105 pub db_name: &'a str,
109 pub table_name: &'a str,
111 pub rowid: i64,
115}
116
117impl SqliteChangeEvent<'_> {
118 pub fn is_from(&self, table: impl NamedTable) -> bool {
134 self.table_name == table.table() && table.schema().is_none_or(|db| self.db_name == db)
135 }
136
137 pub fn rowid_in(&self, table: impl NamedTable) -> Option<i64> {
148 if self.is_from(table) {
149 Some(self.rowid)
150 } else {
151 None
152 }
153 }
154}
155
156trait DynNamedTable {
159 fn schema(&self) -> Option<&str>;
160 fn table(&self) -> &str;
161}
162
163impl<T> DynNamedTable for T
164where
165 T: NamedTable,
166{
167 fn schema(&self) -> Option<&str> {
168 NamedTable::schema(self)
169 }
170
171 fn table(&self) -> &str {
172 NamedTable::table(self)
173 }
174}
175
176struct Route {
177 table: Option<Box<dyn DynNamedTable + Send>>,
178 ops: SqliteChangeOps,
179 callback: Box<dyn FnMut(SqliteChangeEvent<'_>) + Send>,
180}
181
182impl Route {
183 fn matches(&self, event: &SqliteChangeEvent<'_>) -> bool {
184 self.ops.matches_op(event.op)
185 && self.table.as_deref().is_none_or(|name| {
186 name.table() == event.table_name
187 && name.schema().is_none_or(|db| db == event.db_name)
188 })
189 }
190}
191
192#[allow(missing_debug_implementations)]
235pub struct SqliteUpdateRouter {
236 routes: Vec<Route>,
237}
238
239impl SqliteUpdateRouter {
240 pub fn new() -> Self {
242 SqliteUpdateRouter { routes: Vec::new() }
243 }
244
245 pub fn on<T, F>(mut self, table: T, ops: SqliteChangeOps, callback: F) -> Self
254 where
255 T: NamedTable + Send + 'static,
256 F: FnMut(SqliteChangeEvent<'_>) + Send + 'static,
257 {
258 let _ = table;
261 self.routes.push(Route {
262 table: Some(Box::new(table)),
263 ops,
264 callback: Box::new(callback),
265 });
266 self
267 }
268
269 pub fn on_any<F>(mut self, ops: SqliteChangeOps, callback: F) -> Self
271 where
272 F: FnMut(SqliteChangeEvent<'_>) + Send + 'static,
273 {
274 self.routes.push(Route {
275 table: None,
276 ops,
277 callback: Box::new(callback),
278 });
279 self
280 }
281
282 fn dispatch(&mut self, event: SqliteChangeEvent<'_>) {
284 for route in &mut self.routes {
285 if route.matches(&event) {
286 (route.callback)(event);
287 }
288 }
289 }
290
291 pub(crate) fn into_hook(mut self) -> impl FnMut(SqliteChangeEvent<'_>) + Send {
294 move |event| self.dispatch(event)
295 }
296}
297
298impl Default for SqliteUpdateRouter {
299 fn default() -> Self {
300 SqliteUpdateRouter::new()
301 }
302}
303
304#[cfg(test)]
305mod tests {
306 use super::*;
307
308 impl SqliteChangeOps {
310 fn matches(self, op_code: i32) -> bool {
311 self.matches_op(SqliteChangeOp::from_ffi(op_code))
312 }
313 }
314
315 #[test]
316 fn insert_or_delete_matches_both_but_not_update() {
317 let mask = SqliteChangeOps::INSERT | SqliteChangeOps::DELETE;
318 assert!(mask.matches(ffi::SQLITE_INSERT));
319 assert!(mask.matches(ffi::SQLITE_DELETE));
320 assert!(!mask.matches(ffi::SQLITE_UPDATE));
321 }
322
323 #[test]
324 fn all_matches_all_three() {
325 assert!(SqliteChangeOps::ALL.matches(ffi::SQLITE_INSERT));
326 assert!(SqliteChangeOps::ALL.matches(ffi::SQLITE_UPDATE));
327 assert!(SqliteChangeOps::ALL.matches(ffi::SQLITE_DELETE));
328 }
329
330 #[test]
331 fn combining_identical_masks_is_idempotent() {
332 assert_eq!(
333 SqliteChangeOps::INSERT | SqliteChangeOps::INSERT,
334 SqliteChangeOps::INSERT,
335 );
336 }
337
338 #[test]
339 fn contains_single() {
340 assert!(SqliteChangeOps::INSERT.contains(SqliteChangeOps::INSERT));
341 }
342
343 #[test]
344 fn all_contains_insert_or_delete() {
345 assert!(SqliteChangeOps::ALL.contains(SqliteChangeOps::INSERT | SqliteChangeOps::DELETE));
346 }
347
348 #[test]
349 fn insert_does_not_contain_all() {
350 assert!(!SqliteChangeOps::INSERT.contains(SqliteChangeOps::ALL));
351 }
352
353 #[test]
354 fn from_ffi_insert() {
355 assert_eq!(
356 SqliteChangeOp::from_ffi(ffi::SQLITE_INSERT),
357 SqliteChangeOp::Insert
358 );
359 }
360
361 #[test]
362 fn from_ffi_update() {
363 assert_eq!(
364 SqliteChangeOp::from_ffi(ffi::SQLITE_UPDATE),
365 SqliteChangeOp::Update
366 );
367 }
368
369 #[test]
370 fn from_ffi_delete() {
371 assert_eq!(
372 SqliteChangeOp::from_ffi(ffi::SQLITE_DELETE),
373 SqliteChangeOp::Delete
374 );
375 }
376
377 #[test]
378 fn to_ops_roundtrip() {
379 assert_eq!(SqliteChangeOp::Insert.to_ops(), SqliteChangeOps::INSERT);
380 assert_eq!(SqliteChangeOp::Update.to_ops(), SqliteChangeOps::UPDATE);
381 assert_eq!(SqliteChangeOp::Delete.to_ops(), SqliteChangeOps::DELETE);
382 assert_eq!(
383 SqliteChangeOp::Unknown(999).to_ops(),
384 SqliteChangeOps::UNKNOWN
385 );
386 }
387
388 #[test]
389 fn from_ffi_unknown_code() {
390 assert_eq!(SqliteChangeOp::from_ffi(999), SqliteChangeOp::Unknown(999));
391 }
392
393 #[test]
394 fn sqlite_change_event_is_copy() {
395 let event = SqliteChangeEvent {
396 op: SqliteChangeOp::Delete,
397 db_name: "main",
398 table_name: "posts",
399 rowid: 7,
400 };
401 let a = event;
403 let b = event;
404 assert_eq!(a.rowid, b.rowid);
405 }
406
407 #[test]
408 fn debug_formatting() {
409 assert!(format!("{:?}", SqliteChangeOps::INSERT).contains("INSERT"));
413 assert!(format!("{:?}", SqliteChangeOps::DELETE).contains("DELETE"));
414 let _ = format!("{:?}", SqliteChangeOps::empty());
415 let _ = format!("{:?}", SqliteChangeOps::ALL);
416 }
417
418 #[test]
419 fn bitand_works() {
420 let mask = SqliteChangeOps::ALL & SqliteChangeOps::INSERT;
421 assert_eq!(mask, SqliteChangeOps::INSERT);
422 }
423
424 fn make_event(
430 op: SqliteChangeOp,
431 table: &'static str,
432 rowid: i64,
433 ) -> SqliteChangeEvent<'static> {
434 SqliteChangeEvent {
435 op,
436 db_name: "main",
437 table_name: table,
438 rowid,
439 }
440 }
441
442 #[test]
443 fn empty_router_dispatches_nothing() {
444 let mut router = SqliteUpdateRouter::new();
445 router.dispatch(make_event(SqliteChangeOp::Insert, "users", 1));
447 }
448
449 #[test]
450 fn on_any_dispatches_for_every_table() {
451 let fired = std::sync::Arc::new(std::sync::Mutex::new(Vec::new()));
452 let f2 = fired.clone();
453 let mut router = SqliteUpdateRouter::new().on_any(SqliteChangeOps::ALL, move |e| {
454 f2.lock().unwrap().push((e.op, e.rowid));
455 });
456
457 router.dispatch(make_event(SqliteChangeOp::Insert, "users", 1));
458 router.dispatch(make_event(SqliteChangeOp::Delete, "posts", 2));
459
460 assert_eq!(
461 *fired.lock().unwrap(),
462 vec![(SqliteChangeOp::Insert, 1), (SqliteChangeOp::Delete, 2)],
463 );
464 }
465
466 #[test]
467 fn router_filters_by_op_mask() {
468 let fired = std::sync::Arc::new(std::sync::Mutex::new(Vec::new()));
469 let f2 = fired.clone();
470 let mut router = SqliteUpdateRouter::new().on_any(SqliteChangeOps::INSERT, move |e| {
471 f2.lock().unwrap().push(e.rowid);
472 });
473
474 router.dispatch(make_event(SqliteChangeOp::Insert, "users", 1));
475 router.dispatch(make_event(SqliteChangeOp::Update, "users", 2)); router.dispatch(make_event(SqliteChangeOp::Delete, "users", 3)); assert_eq!(*fired.lock().unwrap(), vec![1]);
479 }
480
481 #[test]
482 fn every_matching_route_fires() {
483 let count = std::sync::Arc::new(std::sync::Mutex::new(0u32));
484 let c1 = count.clone();
485 let c2 = count.clone();
486 let mut router = SqliteUpdateRouter::new()
487 .on_any(SqliteChangeOps::ALL, move |_| {
488 *c1.lock().unwrap() += 1;
489 })
490 .on_any(SqliteChangeOps::INSERT, move |_| {
491 *c2.lock().unwrap() += 1;
492 });
493
494 router.dispatch(make_event(SqliteChangeOp::Insert, "users", 1));
496 router.dispatch(make_event(SqliteChangeOp::Delete, "users", 2));
497
498 assert_eq!(*count.lock().unwrap(), 3);
499 }
500}