|
2 | 2 |
|
3 | 3 | use super::operators::*; |
4 | 4 | use crate::expression::{AsExpression, Expression}; |
5 | | -use crate::sql_types::{Array, Nullable, Text}; |
| 5 | +use crate::sql_types::{Array, Nullable, Range, Text}; |
6 | 6 |
|
7 | 7 | /// PostgreSQL specific methods which are present on all expressions. |
8 | 8 | pub trait PgExpressionMethods: Expression + Sized { |
@@ -486,3 +486,71 @@ where |
486 | 486 | T::SqlType: TextOrNullableText, |
487 | 487 | { |
488 | 488 | } |
| 489 | + |
| 490 | +#[doc(hidden)] |
| 491 | +/// Marker trait used to extract the inner type |
| 492 | +/// of our `Range<T>` sql type, used to implement `PgRangeExpressionMethods` |
| 493 | +pub trait RangeHelper { |
| 494 | + type Inner; |
| 495 | +} |
| 496 | + |
| 497 | +impl<ST> RangeHelper for Range<ST> { |
| 498 | + type Inner = ST; |
| 499 | +} |
| 500 | + |
| 501 | +/// PostgreSQL specific methods present on range expressions. |
| 502 | +pub trait PgRangeExpressionMethods: Expression + Sized { |
| 503 | + /// Creates a PostgreSQL `@>` expression. |
| 504 | + /// |
| 505 | + /// This operator returns whether a range contains an specific element |
| 506 | + /// |
| 507 | + /// # Example |
| 508 | + /// |
| 509 | + /// ```rust |
| 510 | + /// # #[macro_use] extern crate diesel; |
| 511 | + /// # include!("../../doctest_setup.rs"); |
| 512 | + /// # |
| 513 | + /// # table! { |
| 514 | + /// # posts { |
| 515 | + /// # id -> Integer, |
| 516 | + /// # versions -> Range<Integer>, |
| 517 | + /// # } |
| 518 | + /// # } |
| 519 | + /// # |
| 520 | + /// # fn main() { |
| 521 | + /// # run_test().unwrap(); |
| 522 | + /// # } |
| 523 | + /// # |
| 524 | + /// # fn run_test() -> QueryResult<()> { |
| 525 | + /// # use self::posts::dsl::*; |
| 526 | + /// # use std::collections::Bound; |
| 527 | + /// # let conn = establish_connection(); |
| 528 | + /// # conn.execute("DROP TABLE IF EXISTS posts").unwrap(); |
| 529 | + /// # conn.execute("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions INT4RANGE NOT NULL)").unwrap(); |
| 530 | + /// # |
| 531 | + /// diesel::insert_into(posts) |
| 532 | + /// .values(versions.eq((Bound::Included(5), Bound::Unbounded))) |
| 533 | + /// .execute(&conn)?; |
| 534 | + /// |
| 535 | + /// let cool_posts = posts.select(id) |
| 536 | + /// .filter(versions.contains(42)) |
| 537 | + /// .load::<i32>(&conn)?; |
| 538 | + /// assert_eq!(vec![1], cool_posts); |
| 539 | + /// |
| 540 | + /// let amazing_posts = posts.select(id) |
| 541 | + /// .filter(versions.contains(1)) |
| 542 | + /// .load::<i32>(&conn)?; |
| 543 | + /// assert!(amazing_posts.is_empty()); |
| 544 | + /// # Ok(()) |
| 545 | + /// # } |
| 546 | + /// ``` |
| 547 | + fn contains<T>(self, other: T) -> Contains<Self, T::Expression> |
| 548 | + where |
| 549 | + Self::SqlType: RangeHelper, |
| 550 | + T: AsExpression<<Self::SqlType as RangeHelper>::Inner>, |
| 551 | + { |
| 552 | + Contains::new(self, other.as_expression()) |
| 553 | + } |
| 554 | +} |
| 555 | + |
| 556 | +impl<T, ST> PgRangeExpressionMethods for T where T: Expression<SqlType = Range<ST>> {} |
0 commit comments