1

I can't find out why the following PodcastEpisode struct

#[derive(Queryable, Identifiable,QueryableByName, Selectable, Debug, PartialEq, Clone, ToSchema,
Serialize, Deserialize)]
pub struct PodcastEpisode {
    #[diesel(sql_type = Integer)]
    pub(crate) id: i32,
    #[diesel(sql_type = Integer)]
    pub(crate) podcast_id: i32,
    #[diesel(sql_type = Text)]
    pub(crate) episode_id: String,
    #[diesel(sql_type = Text)]
    pub(crate) name: String,
    #[diesel(sql_type = Text)]
    pub(crate) url: String,
    #[diesel(sql_type = Text)]
    pub(crate) date_of_recording: String,
    #[diesel(sql_type = Text)]
    pub image_url: String,
    #[diesel(sql_type = Integer)]
    pub total_time: i32,
    #[diesel(sql_type = Text)]
    pub(crate) local_url: String,
    #[diesel(sql_type = Text)]
    pub(crate) local_image_url: String,
    #[diesel(sql_type = Text)]
    pub(crate) description: String,
    #[diesel(sql_type = Text)]
    pub(crate) status: String,
    #[diesel(sql_type = Nullable<Date>)]
    pub(crate) download_time: Option<NaiveDateTime>
}

is giving this error when the following is written. The error comes from conn and is saying the following

error[E0277]: the trait bound `Untyped: load_dsl::private::CompatibleType<PodcastEpisode, Sqlite>` is not satisfied
    --> src\db.rs:755:47
     |
755  |         let res1 = res.load::<PodcastEpisode>(conn).expect("Error loading \
     |                        ----                   ^^^^ the trait `load_dsl::private::CompatibleType<PodcastEpisode, Sqlite>` is not implemented for `Untyped`
     |                        |
     |                        required by a bound introduced by this call
     |
     = help: the trait `load_dsl::private::CompatibleType<U, DB>` is implemented for `Untyped`
     = note: required for `diesel::query_builder::sql_query::UncheckedBind<SqlQuery, &std::string::String, diesel::sql_types::Text>` to implement `LoadQuery<'_, _, PodcastEpisode>`
note: required by a bound in `diesel::RunQueryDsl::load`
    --> <path>\src\github.com-1ecc6299db9ec823\diesel-2.0.3\src\query_dsl\mod.rs:1499:15
     |
1499 |         Self: LoadQuery<'query, Conn, U>,
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load`

    pub fn get_timeline(username_to_search: String, conn: &mut SqliteConnection) {
        let podcast_timeline = sql_query("SELECT podcast_episodes FROM podcasts, podcast_episodes, \
        favorites \
        WHERE podcasts.id = podcast_episodes.podcast_id AND podcasts.id = favorites.podcast_id AND favorites.username=? AND favored=1 ORDER BY podcast_episodes.date_of_recording DESC");

        let res = podcast_timeline.bind::<Text, _>(&username_to_search);


        let res1 = res.load::<PodcastEpisode>(conn).expect("Error loading \
        podcast \
        episode by id");


    }

Meanwhile if I add this struct the application starts. It is the wrong type for the sql query but the application starts:

#[derive(Serialize, Deserialize, Queryable, QueryableByName, Clone, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct PodcastHistoryItem {
    #[diesel(sql_type = Integer)]
    pub id: i32,
    #[diesel(sql_type = Integer)]
    pub podcast_id: i32,
    #[diesel(sql_type = Text)]
    pub episode_id: String,
    #[diesel(sql_type = Integer)]
    pub watched_time: i32,
    #[diesel(sql_type = Text)]
    pub date: String,
    #[diesel(sql_type = Text)]
    pub username: String
}

Relevant table definitions:

Podcasts

diesel::table! {
    podcasts (id) {
        id -> Integer,
        name -> Text,
        directory_id -> Text,
        rssfeed -> Text,
        image_url -> Text,
        summary -> Nullable<Text>,
        language -> Nullable<Text>,
        explicit -> Nullable<Text>,
        keywords -> Nullable<Text>,
        last_build_date -> Nullable<Text>,
        author -> Nullable<Text>,
        active -> Bool,
        original_image_url -> Text,
        directory_name -> Text,
    }
}

Favorites:

diesel::table! {
    favorites (username, podcast_id) {
        username -> Text,
        podcast_id -> Integer,
        favored -> Bool,
    }
}

Podcast Episodes

diesel::table! {
    podcast_episodes (id) {
        id -> Integer,
        podcast_id -> Integer,
        episode_id -> Text,
        name -> Text,
        url -> Text,
        date_of_recording -> Text,
        image_url -> Text,
        total_time -> Integer,
        local_url -> Text,
        local_image_url -> Text,
        description -> Text,
        status -> Text,
        download_time -> Nullable<Timestamp>,
    }
}

The full code can be seen here

Samuel
  • 547
  • 1
  • 3
  • 14
  • 1
    Please include whatever `res` is, the relevant `table!` definitions, and the full error message (as seen from `cargo check`). – kmdreko Apr 19 '23 at 21:31

1 Answers1

0

There is a mismatch in the defined types, at the table! macro download_time is defined as:

    download_time -> Nullable<Timestamp>,

In the struct you define it as:

    #[diesel(sql_type = Nullable<Date>)]
    pub(crate) download_time: Option<NaiveDateTime>

Nullable<Date> and Nullable<Timestamp> are not the same.

You probably meant to write Nullable<Timestamp> in the struct definition.

cafce25
  • 15,907
  • 4
  • 25
  • 31
  • Thanks for the help. How did you know where to look for the error? Did you get any hint from the error logs? The diesel error logs are always like trying to understand Chinese. – Samuel Apr 20 '23 at 06:17
  • 1
    Careful look through what you provided after seeing [this similar question](https://stackoverflow.com/questions/73645993/rust-diesel-error-loading-results-of-a-sql-query-that-select-columns-from-multi) – cafce25 Apr 20 '23 at 06:37
  • I saw this other question but didn’t think that I did that mistake. – Samuel Apr 20 '23 at 08:26