rustrust-dieselrust-diesel-mysql

How to check if value in colum exists using Diesel?


I've been looking for a way to check for a value in my database for a few days now, but I'm running into various problems.

src/schema.rs

diesel::table! {
    qrcode (id) {
        id -> Int4,
        identifier -> Varchar,
        link -> Text,
    }
}

src/models.rs

pub fn find_identifier_value(search_value: &str) -> () {
    let connection = &mut establish_connection();
    use crate::schema::qrcode::dsl::*;

    let result = select(exists(qrcode.filter(crate::schema::qrcode::dsl::identifier.eq(&search_value))))
        .get_result(connection);

    match result {
        Ok(Some(result)) => println!("Post with id"),
        Ok(None) => println!("Unable to find post"),
        Err(_) => println!("An error occured while fetching post"),

}}
error[E0271]: type mismatch resolving `<Bool as SqlType>::IsNull == IsNullable`
    --> src/models.rs:49:21
     |
49   |         .get_result(connection);
     |          ---------- ^^^^^^^^^^ expected `IsNullable`, found `NotNull`
     |          |
     |          required by a bound introduced by this call
     |
     = note: required for `Option<_>` to implement `Queryable<Bool, Mysql>`
     = note: required for `Option<_>` to implement `FromSqlRow<Bool, Mysql>`
     = note: required for `Bool` to implement `load_dsl::private::CompatibleType<Option<_>, Mysql>`
     = note: required for `SelectStatement<NoFromClause, SelectClause<Exists<SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, WhereClause<Grouped<Eq<identifier, Bound<Text, &&str>>>>>>>>` to implement `LoadQuery<'_, MysqlConnection, Option<_>>`


error[E0277]: the trait bound `Option<_>: FromSql<Bool, Mysql>` is not satisfied
    --> src/models.rs:49:21
     |
49   |         .get_result(connection);
     |          ---------- ^^^^^^^^^^ the trait `FromSql<Bool, Mysql>` is not implemented for `Option<_>`, which is required by `SelectStatement<NoFromClause, diesel::query_builder::select_clause::SelectClause<Exists<SelectStatement<FromClause<table>, diesel::query_builder::select_clause::DefaultSelectClause<FromClause<table>>, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::WhereClause<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<columns::identifier, diesel::expression::bound::Bound<diesel::sql_types::Text, &&str>>>>>>>>: LoadQuery<'_, _, _>`
     |          |
     |          required by a bound introduced by this call
     |
     = help: the trait `FromSql<Nullable<_>, Mysql>` is implemented for `Option<_>`
     = help: for that trait implementation, expected `Nullable<_>`, found `Bool`
     = note: required for `Option<_>` to implement `Queryable<Bool, Mysql>`
     = note: required for `Option<_>` to implement `FromSqlRow<Bool, Mysql>`
     = note: required for `Bool` to implement `load_dsl::private::CompatibleType<Option<_>, Mysql>`
     = note: required for `SelectStatement<NoFromClause, SelectClause<Exists<SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, WhereClause<Grouped<Eq<identifier, Bound<Text, &&str>>>>>>>>` to implement `LoadQuery<'_, MysqlConnection, Option<_>>`

I had many attempts with different approaches and functions, through structures and some complex methods, for example find, select, get_result. But they didn't work for similar reasons. I'm trying to find the simplest and most understandable one so that I can use it as a uniqueness check in the future.


Solution

  • Checking if something exists returns a Bool, which you're trying to parse into an Option<_> (inferred from your match). It should just be parsed as a bool instead (documentation).

    You can explicitly annotate what you're expecting from the query like so:

    .get_result::<bool>(connection);
    

    Then your match would look like this:

    match result {
        Ok(true) => println!("Post with id"),
        Ok(false) => println!("Unable to find post"),
        Err(_) => println!("An error occured while fetching post"),
    }