diesel/expression_methods/
text_expression_methods.rs

1use expression::operators::{Concat, Like, NotLike};
2use expression::{AsExpression, Expression};
3use sql_types::{Nullable, Text};
4
5/// Methods present on text expressions
6pub trait TextExpressionMethods: Expression + Sized {
7    /// Concatenates two strings using the `||` operator.
8    ///
9    /// # Example
10    ///
11    /// ```rust
12    /// # #[macro_use] extern crate diesel;
13    /// # include!("../doctest_setup.rs");
14    /// #
15    /// # table! {
16    /// #     users {
17    /// #         id -> Integer,
18    /// #         name -> VarChar,
19    /// #         hair_color -> Nullable<Text>,
20    /// #     }
21    /// # }
22    /// #
23    /// # fn main() {
24    /// #     use self::users::dsl::*;
25    /// #     use diesel::insert_into;
26    /// #
27    /// #     let connection = connection_no_data();
28    /// #     connection.execute("CREATE TABLE users (
29    /// #         id INTEGER PRIMARY KEY,
30    /// #         name VARCHAR(255) NOT NULL,
31    /// #         hair_color VARCHAR(255)
32    /// #     )").unwrap();
33    /// #
34    /// #     insert_into(users)
35    /// #         .values(&vec![
36    /// #             (id.eq(1), name.eq("Sean"), hair_color.eq(Some("Green"))),
37    /// #             (id.eq(2), name.eq("Tess"), hair_color.eq(None)),
38    /// #         ])
39    /// #         .execute(&connection)
40    /// #         .unwrap();
41    /// #
42    /// let names = users.select(name.concat(" the Greatest")).load(&connection);
43    /// let expected_names = vec![
44    ///     "Sean the Greatest".to_string(),
45    ///     "Tess the Greatest".to_string(),
46    /// ];
47    /// assert_eq!(Ok(expected_names), names);
48    ///
49    /// // If the value is nullable, the output will be nullable
50    /// let names = users.select(hair_color.concat("ish")).load(&connection);
51    /// let expected_names = vec![
52    ///     Some("Greenish".to_string()),
53    ///     None,
54    /// ];
55    /// assert_eq!(Ok(expected_names), names);
56    /// # }
57    /// ```
58    fn concat<T: AsExpression<Self::SqlType>>(self, other: T) -> Concat<Self, T::Expression> {
59        Concat::new(self, other.as_expression())
60    }
61
62    /// Returns a SQL `LIKE` expression
63    ///
64    /// This method is case insensitive for SQLite and MySQL.
65    /// On PostgreSQL, `LIKE` is case sensitive. You may use
66    /// [`ilike()`](../expression_methods/trait.PgTextExpressionMethods.html#method.ilike)
67    /// for case insensitive comparison on PostgreSQL.
68    ///
69    /// # Examples
70    ///
71    /// ```rust
72    /// # #[macro_use] extern crate diesel;
73    /// # include!("../doctest_setup.rs");
74    /// #
75    /// # fn main() {
76    /// #     run_test().unwrap();
77    /// # }
78    /// #
79    /// # fn run_test() -> QueryResult<()> {
80    /// #     use schema::users::dsl::*;
81    /// #     let connection = establish_connection();
82    /// #
83    /// let starts_with_s = users
84    ///     .select(name)
85    ///     .filter(name.like("S%"))
86    ///     .load::<String>(&connection)?;
87    /// assert_eq!(vec!["Sean"], starts_with_s);
88    /// #     Ok(())
89    /// # }
90    /// ```
91    fn like<T: AsExpression<Self::SqlType>>(self, other: T) -> Like<Self, T::Expression> {
92        Like::new(self.as_expression(), other.as_expression())
93    }
94
95    /// Returns a SQL `NOT LIKE` expression
96    ///
97    /// This method is case insensitive for SQLite and MySQL.
98    /// On PostgreSQL `NOT LIKE` is case sensitive. You may use
99    /// [`not_ilike()`](../expression_methods/trait.PgTextExpressionMethods.html#method.not_ilike)
100    /// for case insensitive comparison on PostgreSQL.
101    ///
102    /// # Examples
103    ///
104    /// ```rust
105    /// # #[macro_use] extern crate diesel;
106    /// # include!("../doctest_setup.rs");
107    /// #
108    /// # fn main() {
109    /// #     run_test().unwrap();
110    /// # }
111    /// #
112    /// # fn run_test() -> QueryResult<()> {
113    /// #     use schema::users::dsl::*;
114    /// #     let connection = establish_connection();
115    /// #
116    /// let doesnt_start_with_s = users
117    ///     .select(name)
118    ///     .filter(name.not_like("S%"))
119    ///     .load::<String>(&connection)?;
120    /// assert_eq!(vec!["Tess"], doesnt_start_with_s);
121    /// #     Ok(())
122    /// # }
123    /// ```
124    fn not_like<T: AsExpression<Self::SqlType>>(self, other: T) -> NotLike<Self, T::Expression> {
125        NotLike::new(self.as_expression(), other.as_expression())
126    }
127}
128
129#[doc(hidden)]
130/// Marker trait used to implement `TextExpressionMethods` on the appropriate
131/// types. Once coherence takes associated types into account, we can remove
132/// this trait.
133pub trait TextOrNullableText {}
134
135impl TextOrNullableText for Text {}
136impl TextOrNullableText for Nullable<Text> {}
137
138impl<T> TextExpressionMethods for T
139where
140    T: Expression,
141    T::SqlType: TextOrNullableText,
142{
143}