Please explain me how Diesel select works

Hi everybody,

I'm trying to implement Diesel crate and I am lost...
I'm following guide example but with my own classes/tables.

schema.rs (automatically generated by CLI)

table! {
    agencies (id) {
        id -> Varchar,
        label -> Varchar,
        mail -> Varchar,
        uri -> Varchar,
        logo -> Varchar,
    }
}

table! {
    users (mail) {
        mail -> Varchar,
        pass -> Bpchar,
    }
}

allow_tables_to_appear_in_same_query!(
    agencies,
    users,
);

models.rs

#[derive(Queryable)]
pub struct DbUsers {
    pub mail: String,
    pub pass: String,
}

#[derive(Queryable)]
pub struct DbAgencies {
    pub id: String,
    pub label: String,
    pub mail: String,
    pub uri: String,
    pub logo: bool,
}

functions :

// Called by my struct init method
fn get_db_connection(db_uri: String) -> Result<Pool<ConnectionManager<PgConnection>>, ApiError> {
    let connection_manager = ConnectionManager::<PgConnection>::new(db_uri);
    match Pool::builder().build(connection_manager) {
        Ok(p) => Ok(p),
        Err(e) => Err(ApiError::new(format!(
            "Error while initiating database pool : {e}"
        ))),
    }
}

// called for SELECT
pub fn authenticate(&self, login: String, password: String) -> Result<ApiUser, ApiError> {
        match DbUsers::table
            .filter(DbUsers::mail.eq(login))
            .filter(DbUsers::pass.eq(self.hash_password(&password)))
            .load::<DbUsers>(&self.db_connection)
        {
            Ok(u) => Ok(ApiUser::new(u.mail, u.pass)),
            Err(e) => Err(ApiError::new(format!("User '{}' unauthorized", login))),
        }
    }

Errors :

error[E0599]: no function or associated item named `table` found for struct `DbUsers` in the current scope
  --> src\infrastructure\data_access_library.rs:51:24
   |
51 |         match DbUsers::table
   |                        ^^^^^ function or associated item not found in `DbUsers`
   |
  ::: src\infrastructure\db_models\models.rs:2:1
   |
2  | pub struct DbUsers {
   | ------------------ function or associated item `table` not found for this
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `table`, perhaps you need to implement it:
           candidate #1: `HasTable`

error[E0599]: no function or associated item named `mail` found for struct `DbUsers` in the current scope
  --> src\infrastructure\data_access_library.rs:52:30
   |
52 |             .filter(DbUsers::mail.eq(login))
   |                              ^^^^ function or associated item not found in `DbUsers`       
   |
  ::: src\infrastructure\db_models\models.rs:2:1
   |
2  | pub struct DbUsers {
   | ------------------ function or associated item `mail` not found for this

error[E0599]: no function or associated item named `pass` found for struct `DbUsers` in the current scope
  --> src\infrastructure\data_access_library.rs:53:30
   |
53 |             .filter(DbUsers::pass.eq(self.hash_password(&password)))
   |                              ^^^^ function or associated item not found in `DbUsers`       
   |
  ::: src\infrastructure\db_models\models.rs:2:1
   |
2  | pub struct DbUsers {
   | ------------------ function or associated item `pass` not found for this

What do I misunderstand ?
Could you help me please ?

Here's an example select from the guide

    use diesel_demo::schema::posts::dsl::*;

    let connection = establish_connection();
    let results = posts.filter(published.eq(true))
        .limit(5)
        .load::<Post>(&connection)
        .expect("Error loading posts");

Try importing schema::users::dsl::* like in the guide and writing your query with it like

users.filter(mail.eq(login))

and so on.

Oh great ! Thank you !

I did not understand these uses.
For me it was not linked with my problem, I don't know why :sweat_smile:

Now I have just a problem with the 'load' method :

error[E0277]: the trait bound `Pool<ConnectionManager<PgConnection>>: diesel::Connection` is not satisfied
    --> src\infrastructure\data_access_library.rs:57:14
     |
57   |             .load::<DbUsers>(&self.db_connection)
     |              ^^^^ the trait `diesel::Connection` is not implemented for `Pool<ConnectionManager<PgConnection>>`
     |
     = note: required because of the requirements on the impl of `LoadQuery<Pool<ConnectionManager<PgConnection>>, DbUsers>` for `diesel::query_builder::SelectStatement<schema::users::table, query_builder::select_clause::DefaultSelectClause, query_builder::distinct_clause::NoDistinctClause, query_builder::where_clause::WhereClause<And<diesel::expression::operators::Eq<schema::users::columns::mail, diesel::expression::bound::Bound<diesel::sql_types::Text, std::string::String>>, diesel::expression::operators::Eq<schema::users::columns::pass, diesel::expression::bound::Bound<diesel::sql_types::Text, std::string::String>>>>>`
note: required by a bound in `diesel::RunQueryDsl::load`
    --> C:\Users\tony0\.cargo\registry\src\github.com-1ecc6299db9ec823\diesel-1.4.8\src\query_dsl\mod.rs:1238:15
     |
1238 |         Self: LoadQuery<Conn, U>,
     |               ^^^^^^^^^^^^^^^^^^ required by this bound in `diesel::RunQueryDsl::load`

But as I see there, that come from my implementation and not Diesel.

Thanks again ! :smiley:

You code snipped seems to miss details on self.db_connection, but the error message indicates that it's a r2d2 connection pool. That means that you need to checkout a connection from the pool first. You only use a connection with diesels api afterwards. You want to call a function like Pool::get to checkout a connection from the pool.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.