1//! Sqlite specific expression methods.
23pub(in crate::sqlite) use self::private::{
4 BinaryOrNullableBinary, JsonOrNullableJson, JsonOrNullableJsonOrJsonbOrNullableJsonb,
5 MaybeNullableValue, TextOrNullableText, TextOrNullableTextOrBinaryOrNullableBinary,
6};
7use super::operators::*;
8use crate::dsl;
9use crate::expression::grouped::Grouped;
10use crate::expression::{AsExpression, Expression};
11use crate::sql_types::SqlType;
1213/// Sqlite specific methods which are present on all expressions.
14#[cfg(feature = "sqlite")]
15pub trait SqliteExpressionMethods: Expression + Sized {
16/// Creates a Sqlite `IS` expression.
17 ///
18 /// The `IS` operator work like = except when one or both of the operands are NULL.
19 /// In this case, if both operands are NULL, then the `IS` operator evaluates to true.
20 /// If one operand is NULL and the other is not, then the `IS` operator evaluates to false.
21 /// It is not possible for an `IS` expression to evaluate to NULL.
22 ///
23 /// # Example
24 ///
25 /// ```rust
26 /// # include!("../../doctest_setup.rs");
27 /// #
28 /// # fn main() {
29 /// # run_test().unwrap();
30 /// # }
31 /// #
32 /// # fn run_test() -> QueryResult<()> {
33 /// # use schema::animals::dsl::*;
34 /// # let connection = &mut establish_connection();
35 /// let jack_is_a_dog = animals
36 /// .select(name)
37 /// .filter(species.is("dog"))
38 /// .get_results::<Option<String>>(connection)?;
39 /// assert_eq!(vec![Some("Jack".to_string())], jack_is_a_dog);
40 /// # Ok(())
41 /// # }
42 /// ```
43fn is<T>(self, other: T) -> dsl::Is<Self, T>
44where
45Self::SqlType: SqlType,
46 T: AsExpression<Self::SqlType>,
47 {
48 Grouped(Is::new(self, other.as_expression()))
49 }
5051/// Creates a Sqlite `IS NOT` expression.
52 ///
53 /// The `IS NOT` operator work like != except when one or both of the operands are NULL.
54 /// In this case, if both operands are NULL, then the `IS NOT` operator evaluates to false.
55 /// If one operand is NULL and the other is not, then the `IS NOT` operator is true.
56 /// It is not possible for an `IS NOT` expression to evaluate to NULL.
57 ///
58 /// # Example
59 ///
60 /// ```rust
61 /// # include!("../../doctest_setup.rs");
62 /// #
63 /// # fn main() {
64 /// # run_test().unwrap();
65 /// # }
66 /// #
67 /// # fn run_test() -> QueryResult<()> {
68 /// # use schema::animals::dsl::*;
69 /// # let connection = &mut establish_connection();
70 /// let jack_is_not_a_spider = animals
71 /// .select(name)
72 /// .filter(species.is_not("spider"))
73 /// .get_results::<Option<String>>(connection)?;
74 /// assert_eq!(vec![Some("Jack".to_string())], jack_is_not_a_spider);
75 /// # Ok(())
76 /// # }
77 /// ```
78#[allow(clippy::wrong_self_convention)] // This is named after the sql operator
79fn is_not<T>(self, other: T) -> dsl::IsNot<Self, T>
80where
81Self::SqlType: SqlType,
82 T: AsExpression<Self::SqlType>,
83 {
84 Grouped(IsNot::new(self, other.as_expression()))
85 }
86}
8788impl<T: Expression> SqliteExpressionMethods for T {}
8990pub(in crate::sqlite) mod private {
91use crate::sql_types::{Binary, Json, Jsonb, MaybeNullableType, Nullable, SingleValue, Text};
9293#[diagnostic::on_unimplemented(
94 message = "`{Self}` is neither `diesel::sql_types::Text` nor `diesel::sql_types::Nullable<Text>`",
95 note = "try to provide an expression that produces one of the expected sql types"
96)]
97pub trait TextOrNullableText {}
9899impl TextOrNullableText for Text {}
100impl TextOrNullableText for Nullable<Text> {}
101102#[diagnostic::on_unimplemented(
103 message = "`{Self}` is neither `diesel::sql_types::Binary` nor `diesel::sql_types::Nullable<Binary>`",
104 note = "try to provide an expression that produces one of the expected sql types"
105)]
106pub trait BinaryOrNullableBinary {}
107108impl BinaryOrNullableBinary for Binary {}
109impl BinaryOrNullableBinary for Nullable<Binary> {}
110111#[diagnostic::on_unimplemented(
112 message = "`{Self}` is neither `diesel::sql_types::Text`, `diesel::sql_types::Nullable<Text>`, `diesel::sql_types::Binary` nor `diesel::sql_types::Nullable<Binary>`",
113 note = "try to provide an expression that produces one of the expected sql types"
114)]
115pub trait TextOrNullableTextOrBinaryOrNullableBinary {}
116117impl TextOrNullableTextOrBinaryOrNullableBinary for Text {}
118impl TextOrNullableTextOrBinaryOrNullableBinary for Nullable<Text> {}
119impl TextOrNullableTextOrBinaryOrNullableBinary for Binary {}
120impl TextOrNullableTextOrBinaryOrNullableBinary for Nullable<Binary> {}
121122#[diagnostic::on_unimplemented(
123 message = "`{Self}` is neither `diesel::sql_types::Json`, `diesel::sql_types::Jsonb`, `diesel::sql_types::Nullable<Json>` nor `diesel::sql_types::Nullable<Jsonb>`",
124 note = "try to provide an expression that produces one of the expected sql types"
125)]
126pub trait JsonOrNullableJsonOrJsonbOrNullableJsonb {}
127impl JsonOrNullableJsonOrJsonbOrNullableJsonb for Json {}
128impl JsonOrNullableJsonOrJsonbOrNullableJsonb for Nullable<Json> {}
129impl JsonOrNullableJsonOrJsonbOrNullableJsonb for Jsonb {}
130impl JsonOrNullableJsonOrJsonbOrNullableJsonb for Nullable<Jsonb> {}
131132#[diagnostic::on_unimplemented(
133 message = "`{Self}` is neither `diesel::sql_types::Json` nor `diesel::sql_types::Nullable<Json>`",
134 note = "try to provide an expression that produces one of the expected sql types"
135)]
136pub trait JsonOrNullableJson {}
137impl JsonOrNullableJson for Json {}
138impl JsonOrNullableJson for Nullable<Json> {}
139140pub trait MaybeNullableValue<T>: SingleValue {
141type Out: SingleValue;
142 }
143144impl<T, O> MaybeNullableValue<O> for T
145where
146T: SingleValue,
147 T::IsNull: MaybeNullableType<O>,
148 <T::IsNull as MaybeNullableType<O>>::Out: SingleValue,
149 {
150type Out = <T::IsNull as MaybeNullableType<O>>::Out;
151 }
152}